如何覆盖凤凰中的错误?

How to override errors in phoenix?

我在 phoenix 上构建 restful api (json)。而且我不需要html.

的支持

如何覆盖 phoenix 中的错误?示例错误: - 500 - 404 找不到路由 和其他

您需要自定义 MyApp.ErrorView。 Phoenix 在 web/views/error_view.ex 中为您生成此文件。模板的默认内容可以找到on Github.

另请参阅 the docs on custom errors,尽管它们似乎有点过时,因为它们指示您使用 MyApp.ErrorsView(复数),后者被替换为 MyApp.ErrorView

对于那些可能遇到与我相同问题的人,需要几个步骤来呈现 JSON 404 和 500 响应。

首先将 render("404.json", _assigns)render("500.json", _assigns) 添加到您应用的 web/views/error_view.ex 文件中。

例如:

defmodule MyApp.ErrorView do
  use MyApp.Web, :view

  def render("404.json", _assigns) do
    %{errors: %{message: "Not Found"}}
  end

  def render("500.json", _assigns) do
    %{errors: %{message: "Server Error"}}
  end
end

然后在您的 config/config.exs 文件中将 default_format 更新为 "json"

config :my_app, MyApp.Endpoint,
  render_errors: [default_format: "json"]

请注意,如果您的应用是纯粹的 REST api,这会很好,但如果您还呈现 HTML 响应,请小心,因为现在默认错误将呈现为 json.

您可以在 router.ex 中用 plug :accepts, ["json"] 覆盖 400-500 个错误。例如:

# config/config.exs
...
config :app, App.endpoint,
  ...
  render_errors: [accepts: ~w(html json)],
  ...    

# web/views/error_view.ex
defmodule App.ErrorView do
 use App.Web, :view

 def render("404.json", _assigns) do
   %{errors: %{message: "Not Found"}}
 end

 def render("500.json", _assigns) do
   %{errors: %{message: "Server Error"}}
 end
end


# in router.ex
defmodule App.Router do
 use App.Web, :router

 pipeline :api do
   plug :accepts, ["json"]
 end

 pipe_through :api

 # put here your routes
 post '/foo/bar'...

 # or in scope: 
 scope '/foo' do
   pipe_through :api
   get 'bar' ...
 end

它会起作用。

None 以上答案对我有用。 我能够让 phoenix 仅对 api 端点使用 json 的唯一方法是这样编辑端点设置:

config :app, App.Endpoint,
       render_errors: [
         view: App.ErrorView,
         accepts: ~w(json html) # json has to be in before html otherwise only html will be used
       ]

json 的想法必须是要呈现 html 的世界列表中的第一个,有点奇怪但它有效。

然后有一个如下所示的 ErrorView :

defmodule App.ErrorView do
  use App, :view

  def render("400.json", _assigns) do
    %{errors: %{message: "Bad request"}}
  end

  def render("404.json", _assigns) do
    %{errors: %{message: "Not Found"}}
  end

  def render("500.json", _assigns) do
    %{errors: %{message: "Server Error"}}
  end
end

与这里的其他答案没有什么不同,我只是添加了一个 400 错误的请求,因为我 运行 到它,你也应该:添加你可能 运行 到的任何东西。

最后在我的路由器代码中:

pipeline :api do
  plug(:accepts, ["json"])
end
pipeline :browser do
  plug(:accepts, ["html"])
  ...
end

与其他答案没有什么不同,但您必须确保您的管道配置正确。