Ошибка аргумента при получении данных из 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"