Ошибка аргумента при получении данных из API и декодировании с помощью Poison

Я новичок в Elixir/Phoenix и пытаюсь учиться, создав небольшое приложение.

Я получаю данные из стороннего API и получаю следующую ошибку.

(ArgumentError) argument error :erlang.iolist_to_binary([%{"24h_volume" => "1000", "name" => "some_name"},{...}])

В моем контроллере есть:

HTTPoison.start

%HTTPoison.Response{body: body} = HTTPoison.get!(url)
body = body
       |> Poison.decode!(keys: :atoms!)

Это не работает. Я использовал (keys::atom), что не рекомендуется в документации по Poison.

Вот моя схема:

schema "things" do
  field :name, :string
  field :volume_24h, :float

  timestamps()
end

@doc false
def changeset(%Thing{} = thing, attrs) do
  thing
  |> cast(attrs, [:volume_24h, :name])
  |> validate_not_nil([:volume_24h, :name])
end

def validate_not_nil(changeset, fields) do
  Enum.reduce(fields, changeset, fn field, changeset ->
    if get_field(changeset, field) == nil do
      add_error(changeset, field, "nil")
    else
      changeset
    end
  end)
end

Я пытаюсь использовать другое имя поля для "24h_volume", и я получаю эту ошибку:

(ArgumentError) argument error :erlang.binary_to_existing_atom("24h_volume", :utf8)

Я явно что-то здесь упускаю.

Есть ли способ передать желаемое имя поля в Poison, потому что "24h_volume" не будет допустимым атомом? Как я могу исправить эти ошибки?

2 ответа

Решение

У тебя беспорядок с volume_24h параметр.

Как указано в Poison документация:

Обратите внимание, что keys: :atoms! повторно использует существующие атомы, т.е. если :name не был выделен до вызова, вы увидите сообщение об ошибке аргумента.

Это именно то, что происходит. Приложение ожидает :volume_24h ключ, чтобы прийти от запроса, но он (по какой-то причине, возможно, из-за неправильной конфигурации формы как) получает 24h_volume, Используя разрешительный atoms звоните вместо atoms! Вы ничего не решили, у вас есть проблема скрыта. Что на самом деле происходит, 24h_volume ключ приходит и эффективно сбрасывается при вызове cast,

Вам нужно либо исправить отправителя fronend / request для отправки volume_24h ключ или исправить контроллер, чтобы принять :"24h_volume" ключ.


Есть две причины, препятствующие atoms использование. Один описан в Poison документация: так называемая "атака DOS для атомов" возможна, когда случайные запросы имеют случайные ключи, которые впоследствии выдаются, переполняя хранилище атомов. Во-вторых, используя версию с грохотом atoms! каждый защищает себя от опечаток / неправильной конфигурации, как показано выше.

FWIW, атом для правильного ключа выделяется в определении схемы.

Вы должны определить свой атом следующим образом, потому что ваш атом обычно недопустим, чтобы начинаться с числа, но вы можете обойти это, обернув его "

Так что измени свой атом следующим образом:

:"24_volume"
Другие вопросы по тегам