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 доступен.

Итак, мои вопросы, в возрастающей абстрактности:

  1. Как мне поднять ParseError из парсера без исключения источника?
  2. Нужно ли поднимать ParseError Или лучше поднять собственное исключение?
  3. Есть ли вообще лучший способ, позволяющий мне проверять подпись без повторной реализации анализа JSON?

2 ответа

Как мне поднять ParseError из парсера без исключения источника?

Вы должны создать Plug.Parsers.ParseError сам:

raise %Plug.Parsers.ParseError{exception: %MyException{message: "Failed to parse"}}

Нужно ли поднимать ParseError Или лучше поднять собственное исключение?

Вы можете поднять все, что хотите, но так как это действительно ParseError Я не вижу смысла поднимать что-то другое.

Есть ли лучший способ вообще [...]

Этот слишком самоуверенный. JSON-разбор, кажется, в порядке.

(Я бы предпочел, чтобы Plug.Parsers.JSON сделать это, но мне нужно прочитать необработанное тело запроса, чтобы проверить его на соответствие подписи, так что это невозможно).

...

  1. Есть ли вообще лучший способ, позволяющий мне проверять подпись без повторной реализации анализа 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
Другие вопросы по тегам