【问题标题】:Getting argument error when fetching data from API and decoding with Poison从 API 获取数据并使用 Poison 解码时出现参数错误
【发布时间】:2018-06-10 20:06:06
【问题描述】:

我是 Elixir/Phoenix 的新手,正在尝试通过构建一个小应用来学习。

我正在从第 3 方 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: :atoms),这在 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”不是有效的原子? 如何修复这些错误?

【问题讨论】:

    标签: elixir phoenix-framework elixir-poison httpoison


    【解决方案1】:

    volume_24h 参数搞砸了。

    正如Poison documentation中所述:

    请注意,keys: :atoms! 重用现有原子,即如果在调用之前未分配 :name,您将遇到参数错误消息。

    这正是发生的事情。应用程序希望 :volume_24h 密钥来自请求,但它(出于某种原因,可能是由于 like 的表单配置错误)接收到 24h_volume。通过使用允许的atoms 调用而不是atoms!,您没有解决任何问题,隐藏了问题。实际发生了什么,24h_volume 键来了,cast 调用有效地丢弃

    您需要修复前端/请求发送方以发送volume_24h 密钥,或修复控制器以接受:"24h_volume" 密钥。


    不鼓励使用atoms 有两个原因。一种在Poison 文档中进行了描述:所谓的“原子 DOS 攻击”是可能的,具有随后发出的随机密钥的随机请求,溢出原子存储。第二个是通过使用 banged 版本atoms! 可以保护自己免受上述错误/错误配置的影响。

    FWIW,正确键的原子正在模式定义中分配。

    【讨论】:

    • 感谢您抽出宝贵时间回答。我不知道我可以使用 :"24h_volume" 这就是我在迁移文件中设置 :volume_24h 并想更改我从 Poison 获得的密钥的原因。我想知道是否有类似的东西。 Poison.decode!(事物,键::atoms!,字段:{volume_24h:“24h_volume”})
    • 我很确定没有。这种转换与 json 编码无关,我怀疑它是否有有意义的用例。
    【解决方案2】:

    你有如下定义你的原子,因为你的原子通常以数字开头是非法的,但你可以用"包装它来绕过它

    所以改变你的原子如下:

    :"24_volume"
    

    【讨论】:

    • 此说法本身正确,但与问题无关。检查我的答案以获得正确的解释。
    • 是的,我已经看到一个原子不能以数字开头,我完全错过了这个:“string”这显然是一个正确的答案,但对这种灵丹妙药的东西不熟悉stackoverflow.com/users/2035262/mudasobwa 的答案信息量更大。谢谢!
    • @mudasobwa,我明白了。我认为他得到的 json 是因为他收到的 json。
    • @alexts 很高兴您找到了您正在寻找的答案!
    猜你喜欢
    • 2021-06-20
    • 1970-01-01
    • 2013-07-09
    • 2019-03-08
    • 2022-11-07
    • 2017-01-04
    • 1970-01-01
    • 2020-11-22
    • 2017-03-03
    相关资源
    最近更新 更多