Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Elixir 无法对错误消息进行编码_Elixir_Phoenix Framework_Elixir Poison - Fatal编程技术网

Elixir 无法对错误消息进行编码

Elixir 无法对错误消息进行编码,elixir,phoenix-framework,elixir-poison,Elixir,Phoenix Framework,Elixir Poison,我使用phoenix作为JSON API。我的一个模型如下所示,除非唯一约束检查失败,否则该模型运行良好。发生这种情况时,我会出现以下错误: (Poison.EncodeError) unable to encode value: {"Email address is already registered", []} 型号: defmodule MyApp.Registration do use MyApp.Web, :model @derive {Poison.Encoder, o

我使用phoenix作为JSON API。我的一个模型如下所示,除非唯一约束检查失败,否则该模型运行良好。发生这种情况时,我会出现以下错误:

(Poison.EncodeError) unable to encode value: {"Email address is already registered", []}
型号

defmodule MyApp.Registration do
  use MyApp.Web, :model

  @derive {Poison.Encoder, only: [:name, :email, :category]}
  schema "registrations" do
    field :name, :string
    field :category, :string
    field :email, :string

    timestamps
  end

  def changeset(model, params \\ :empty) do
    model
    |> cast(params, ~w(name email category), [])
    |> validate_length(:name, min: 1, max: 240)
    |> unique_constraint(:email, message: "Email address is already registered")
  end

end
def create(conn, registration_params) do
  changeset = Registration.changeset(%Registration{}, registration_params)
  case  Repo.insert(changeset) do
    {:ok, _registration} ->
      # Success 
    {:error, error} ->
      conn
      |> put_status(:unprocessable_entity)
      |> render(MyApp.ErrorView, "generic.json", error: error)
  end
end
def render("generic.json", error) do
  error
end
def translate_errors(changeset) do
  Ecto.Changeset.traverse_errors(changeset, &translate_error/1)
end

def render("error.json", %{changeset: changeset}) do
  # When encoded, the changeset returns its errors
  # as a JSON object. So we just pass it forward.
  %{errors: translate_errors(changeset)}
end
def create(conn, registration_params) do
  changeset = Registration.changeset(%Registration{}, registration_params)
  case  Repo.insert(changeset) do
    {:ok, _registration} ->
      # Success 
    {:error, changeset} ->
      conn
      |> put_status(:unprocessable_entity)
      |> render(MyApp.ErrorView, "error.json", changeset: changeset)
  end
end
defmodule MyAppWeb.ErrorHelpers do
  def translate_error({msg, opts}) do
    if count = opts[:count] do
      Gettext.dngettext(MyAppWeb.Gettext, "errors", msg, msg, count, opts)
    else
      Gettext.dgettext(MyAppWeb.Gettext, "errors", msg, opts)
    end
  end
end
控制器

defmodule MyApp.Registration do
  use MyApp.Web, :model

  @derive {Poison.Encoder, only: [:name, :email, :category]}
  schema "registrations" do
    field :name, :string
    field :category, :string
    field :email, :string

    timestamps
  end

  def changeset(model, params \\ :empty) do
    model
    |> cast(params, ~w(name email category), [])
    |> validate_length(:name, min: 1, max: 240)
    |> unique_constraint(:email, message: "Email address is already registered")
  end

end
def create(conn, registration_params) do
  changeset = Registration.changeset(%Registration{}, registration_params)
  case  Repo.insert(changeset) do
    {:ok, _registration} ->
      # Success 
    {:error, error} ->
      conn
      |> put_status(:unprocessable_entity)
      |> render(MyApp.ErrorView, "generic.json", error: error)
  end
end
def render("generic.json", error) do
  error
end
def translate_errors(changeset) do
  Ecto.Changeset.traverse_errors(changeset, &translate_error/1)
end

def render("error.json", %{changeset: changeset}) do
  # When encoded, the changeset returns its errors
  # as a JSON object. So we just pass it forward.
  %{errors: translate_errors(changeset)}
end
def create(conn, registration_params) do
  changeset = Registration.changeset(%Registration{}, registration_params)
  case  Repo.insert(changeset) do
    {:ok, _registration} ->
      # Success 
    {:error, changeset} ->
      conn
      |> put_status(:unprocessable_entity)
      |> render(MyApp.ErrorView, "error.json", changeset: changeset)
  end
end
defmodule MyAppWeb.ErrorHelpers do
  def translate_error({msg, opts}) do
    if count = opts[:count] do
      Gettext.dngettext(MyAppWeb.Gettext, "errors", msg, msg, count, opts)
    else
      Gettext.dgettext(MyAppWeb.Gettext, "errors", msg, opts)
    end
  end
end
查看

defmodule MyApp.Registration do
  use MyApp.Web, :model

  @derive {Poison.Encoder, only: [:name, :email, :category]}
  schema "registrations" do
    field :name, :string
    field :category, :string
    field :email, :string

    timestamps
  end

  def changeset(model, params \\ :empty) do
    model
    |> cast(params, ~w(name email category), [])
    |> validate_length(:name, min: 1, max: 240)
    |> unique_constraint(:email, message: "Email address is already registered")
  end

end
def create(conn, registration_params) do
  changeset = Registration.changeset(%Registration{}, registration_params)
  case  Repo.insert(changeset) do
    {:ok, _registration} ->
      # Success 
    {:error, error} ->
      conn
      |> put_status(:unprocessable_entity)
      |> render(MyApp.ErrorView, "generic.json", error: error)
  end
end
def render("generic.json", error) do
  error
end
def translate_errors(changeset) do
  Ecto.Changeset.traverse_errors(changeset, &translate_error/1)
end

def render("error.json", %{changeset: changeset}) do
  # When encoded, the changeset returns its errors
  # as a JSON object. So we just pass it forward.
  %{errors: translate_errors(changeset)}
end
def create(conn, registration_params) do
  changeset = Registration.changeset(%Registration{}, registration_params)
  case  Repo.insert(changeset) do
    {:ok, _registration} ->
      # Success 
    {:error, changeset} ->
      conn
      |> put_status(:unprocessable_entity)
      |> render(MyApp.ErrorView, "error.json", changeset: changeset)
  end
end
defmodule MyAppWeb.ErrorHelpers do
  def translate_error({msg, opts}) do
    if count = opts[:count] do
      Gettext.dngettext(MyAppWeb.Gettext, "errors", msg, msg, count, opts)
    else
      Gettext.dgettext(MyAppWeb.Gettext, "errors", msg, opts)
    end
  end
end
我想我可能需要以某种方式将错误消息添加到
Poison.Encoder中,仅限于:[]
列表,但我不确定如何做到这一点

编辑


我应该澄清,如果我没有指定自定义错误,我仍然会收到与通用错误消息相同的错误。

我认为如果使用
mix phoenix.gen.json
,这是自动完成的,但是变更集错误需要转换为json

查看

defmodule MyApp.Registration do
  use MyApp.Web, :model

  @derive {Poison.Encoder, only: [:name, :email, :category]}
  schema "registrations" do
    field :name, :string
    field :category, :string
    field :email, :string

    timestamps
  end

  def changeset(model, params \\ :empty) do
    model
    |> cast(params, ~w(name email category), [])
    |> validate_length(:name, min: 1, max: 240)
    |> unique_constraint(:email, message: "Email address is already registered")
  end

end
def create(conn, registration_params) do
  changeset = Registration.changeset(%Registration{}, registration_params)
  case  Repo.insert(changeset) do
    {:ok, _registration} ->
      # Success 
    {:error, error} ->
      conn
      |> put_status(:unprocessable_entity)
      |> render(MyApp.ErrorView, "generic.json", error: error)
  end
end
def render("generic.json", error) do
  error
end
def translate_errors(changeset) do
  Ecto.Changeset.traverse_errors(changeset, &translate_error/1)
end

def render("error.json", %{changeset: changeset}) do
  # When encoded, the changeset returns its errors
  # as a JSON object. So we just pass it forward.
  %{errors: translate_errors(changeset)}
end
def create(conn, registration_params) do
  changeset = Registration.changeset(%Registration{}, registration_params)
  case  Repo.insert(changeset) do
    {:ok, _registration} ->
      # Success 
    {:error, changeset} ->
      conn
      |> put_status(:unprocessable_entity)
      |> render(MyApp.ErrorView, "error.json", changeset: changeset)
  end
end
defmodule MyAppWeb.ErrorHelpers do
  def translate_error({msg, opts}) do
    if count = opts[:count] do
      Gettext.dngettext(MyAppWeb.Gettext, "errors", msg, msg, count, opts)
    else
      Gettext.dgettext(MyAppWeb.Gettext, "errors", msg, opts)
    end
  end
end
控制器

defmodule MyApp.Registration do
  use MyApp.Web, :model

  @derive {Poison.Encoder, only: [:name, :email, :category]}
  schema "registrations" do
    field :name, :string
    field :category, :string
    field :email, :string

    timestamps
  end

  def changeset(model, params \\ :empty) do
    model
    |> cast(params, ~w(name email category), [])
    |> validate_length(:name, min: 1, max: 240)
    |> unique_constraint(:email, message: "Email address is already registered")
  end

end
def create(conn, registration_params) do
  changeset = Registration.changeset(%Registration{}, registration_params)
  case  Repo.insert(changeset) do
    {:ok, _registration} ->
      # Success 
    {:error, error} ->
      conn
      |> put_status(:unprocessable_entity)
      |> render(MyApp.ErrorView, "generic.json", error: error)
  end
end
def render("generic.json", error) do
  error
end
def translate_errors(changeset) do
  Ecto.Changeset.traverse_errors(changeset, &translate_error/1)
end

def render("error.json", %{changeset: changeset}) do
  # When encoded, the changeset returns its errors
  # as a JSON object. So we just pass it forward.
  %{errors: translate_errors(changeset)}
end
def create(conn, registration_params) do
  changeset = Registration.changeset(%Registration{}, registration_params)
  case  Repo.insert(changeset) do
    {:ok, _registration} ->
      # Success 
    {:error, changeset} ->
      conn
      |> put_status(:unprocessable_entity)
      |> render(MyApp.ErrorView, "error.json", changeset: changeset)
  end
end
defmodule MyAppWeb.ErrorHelpers do
  def translate_error({msg, opts}) do
    if count = opts[:count] do
      Gettext.dngettext(MyAppWeb.Gettext, "errors", msg, msg, count, opts)
    else
      Gettext.dgettext(MyAppWeb.Gettext, "errors", msg, opts)
    end
  end
end
编辑

添加
translate\u错误\1
函数定义。这包含在名为
MyApp.ErrorHelpers
的模块中,该模块导入到
web/my_app.ex
lib/my_app\u web.ex
中的
视图
函数定义中,具体取决于您的phoenix版本

lib/my\u app\u web/views/error\u helpers.ex

defmodule MyApp.Registration do
  use MyApp.Web, :model

  @derive {Poison.Encoder, only: [:name, :email, :category]}
  schema "registrations" do
    field :name, :string
    field :category, :string
    field :email, :string

    timestamps
  end

  def changeset(model, params \\ :empty) do
    model
    |> cast(params, ~w(name email category), [])
    |> validate_length(:name, min: 1, max: 240)
    |> unique_constraint(:email, message: "Email address is already registered")
  end

end
def create(conn, registration_params) do
  changeset = Registration.changeset(%Registration{}, registration_params)
  case  Repo.insert(changeset) do
    {:ok, _registration} ->
      # Success 
    {:error, error} ->
      conn
      |> put_status(:unprocessable_entity)
      |> render(MyApp.ErrorView, "generic.json", error: error)
  end
end
def render("generic.json", error) do
  error
end
def translate_errors(changeset) do
  Ecto.Changeset.traverse_errors(changeset, &translate_error/1)
end

def render("error.json", %{changeset: changeset}) do
  # When encoded, the changeset returns its errors
  # as a JSON object. So we just pass it forward.
  %{errors: translate_errors(changeset)}
end
def create(conn, registration_params) do
  changeset = Registration.changeset(%Registration{}, registration_params)
  case  Repo.insert(changeset) do
    {:ok, _registration} ->
      # Success 
    {:error, changeset} ->
      conn
      |> put_status(:unprocessable_entity)
      |> render(MyApp.ErrorView, "error.json", changeset: changeset)
  end
end
defmodule MyAppWeb.ErrorHelpers do
  def translate_error({msg, opts}) do
    if count = opts[:count] do
      Gettext.dngettext(MyAppWeb.Gettext, "errors", msg, msg, count, opts)
    else
      Gettext.dgettext(MyAppWeb.Gettext, "errors", msg, opts)
    end
  end
end

错误是exto.Changeset的一部分,而不是模型,因此看起来很奇怪。能否提供呈现json的控制器代码和可能的视图代码?@Svilen添加了控制器和视图代码。我尝试了几种将变更集错误传递到json视图的方法,但到目前为止没有任何乐趣。你知道
translate_error/1
函数是在哪里定义的吗?@Jean PierreBécotte我已经用函数定义更新了答案。干得好,@Razzildinho!