Poison.EncodeError无法编码值:{"已经采取了",[]}

时间:2017-10-31 07:37:36

标签: elixir phoenix-framework elixir-poison

我正在尝试返回无效的变更集。

做的时候

conn
|> put_status(422)
|> put_view(Elemental.Auth.ErrorView)
|> render("422.json-api", %{data: changeset})

OR

conn
|> put_status(422)
|> put_view(Elemental.Auth.ErrorView)
|> render(:errors, data: changeset)

使用JaSerializer 我正在

(Poison.EncodeError) unable to encode value: {"has already been taken", []}

这是出乎意料的。它早先工作了。 我有{:poison, "~> 2.0"},

更新

>> d
%{errors: [shortcode: {"has invalid format", [validation: :format]}]}
iex(11)> Map.replace(d, :errors, [shortcode: Tuple.to_list(shortcode)]) |> Poison.encode
{:error,
 {:invalid, {:shortcode, ["has invalid format", [validation: :format]]}}}

1 个答案:

答案 0 :(得分:1)

毒药永远不知道如何encode元组。您可以轻松地将元组转换为列表:

a = {"has already been taken", []}

a 
|> Tuple.to_list() # ["has already been taken", []]
|> Poison.encode!() # "[\"has already been taken\",[]]"

或者只是使用模式匹配从元组中获取first_entry:

{message, _list} = {"has already been taken", []}

修改

尝试显式显示changeset时,代码崩溃了。避免这种情况的最佳解决方案是创建特定视图,该视图将返回JSON,您可以在其中准备如何显示错误,例如。

def render("422.json-api", %{data: data}) do
  # data is actually changeset, which you are passing here
  errors = Enum.map(data.errors, fn {field, message} -> 
    %{field: "#{field} has error: #{message}"
  end)

  %{errors: errors}
end