10

我在 phoenix 上构建了 restful api (json)。而且我不需要html的支持。

如何覆盖凤凰中的错误?示例错误: - 500 - 404 未找到路由等。

4

4 回答 4

8

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

首先将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。

于 2015-07-29T00:45:46.967 回答
4

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

另请参阅有关自定义错误的文档,尽管它们似乎有点过时,因为它们指示您使用MyApp.ErrorsView(复数),已替换为MyApp.ErrorView

于 2015-02-21T08:03:37.390 回答
1

上面的答案都不适合我。我能够让 phoenixjson仅用于 api 端点的唯一方法是以这种方式编辑端点设置:

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

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

于 2018-12-29T18:50:33.910 回答
0

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

# 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

它会起作用。

于 2016-03-22T05:17:58.600 回答