Plug Parser: повышение ParseError
Я пишу Plug Parser, который, помимо прочего, декодирует JSON с использованием Poison (я бы предпочел, чтобы Plug.Parsers.JSON
сделать это, но мне нужно прочитать необработанное тело запроса, чтобы проверить его на соответствие подписи, так что это невозможно).
я использую Poison.decode/2
расшифровать JSON. Это возвращает {:error, ...}
кортеж по ошибке. Как парсер Plug, я думаю, что должен повысить Plug.Parsers.ParseError
если произошла ошибка при разборе. тем не мение ParseError
ожидает exception
структура. У меня нет одного из них, у меня только кортеж возвращается Poison.decode/2
,
В качестве обходного пути я могу использовать использование Poison.decode!/2
а также rescue
поднятая ошибка, повторно поднимая это как ParseError
, но это кажется странным, когда не поднимая decode/2
доступен.
Итак, мои вопросы, в возрастающей абстрактности:
- Как мне поднять
ParseError
из парсера без исключения источника? - Нужно ли поднимать
ParseError
Или лучше поднять собственное исключение? - Есть ли вообще лучший способ, позволяющий мне проверять подпись без повторной реализации анализа JSON?
2 ответа
Как мне поднять
ParseError
из парсера без исключения источника?
Вы должны создать Plug.Parsers.ParseError
сам:
raise %Plug.Parsers.ParseError{exception: %MyException{message: "Failed to parse"}}
Нужно ли поднимать
ParseError
Или лучше поднять собственное исключение?
Вы можете поднять все, что хотите, но так как это действительно ParseError
Я не вижу смысла поднимать что-то другое.
Есть ли лучший способ вообще [...]
Этот слишком самоуверенный. JSON-разбор, кажется, в порядке.
(Я бы предпочел, чтобы
Plug.Parsers.JSON
сделать это, но мне нужно прочитать необработанное тело запроса, чтобы проверить его на соответствие подписи, так что это невозможно).
...
- Есть ли вообще лучший способ, позволяющий мне проверять подпись без повторной реализации анализа JSON?
Позволить Plug.Parsers.JSON
сделать это на самом деле лучший вариант. Начиная с версии 1.5.1, можно предоставить настраиваемый читатель тела анализатору, который может кэшировать тело для дальнейшего использования. Это гораздо более общее решение, чем повторная реализация плагина JSON-parser.
Вот мой пользовательский читатель:
def read_body(conn, opts) do
case Plug.Conn.read_body(conn, opts) do
{res, body, conn} when res in [:ok, :more] ->
{res, body, update_in(conn.assigns[:raw_body], &((&1 || "") <> body))}
unknown ->
unknown
end
end