【问题标题】:How to override errors in phoenix?如何覆盖凤凰中的错误?
【发布时间】:2018-12-31 06:38:25
【问题描述】:

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

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

【问题讨论】:

    标签: elixir phoenix-framework


    【解决方案1】:

    对于那些可能遇到与我相同的问题的人,需要几个步骤来为 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。

    【讨论】:

    • 不知道为什么这被否决了。该答案对我有用,而接受的答案则无效。我没有修改 default_format,而是通过删除 html 值修改了“接受”。
    【解决方案2】:

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

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

    【讨论】:

    • 是的,我看到了。但对我不起作用,也许我做错了什么。示例 - gist.github.com/saa/c175ae731e32790de17f
    • 这个答案是正确的。不幸的是,错误处理中有一个错误可以避免触发自定义错误。如果您暂时将plug :accepts, ... 从路由器移动到端点,它可能会起作用。否则请等待新的 Phoenix 版本。
    • 如何在端点中正确指定?如果只是 - plug :accepts, ~w(json) 我有错误函数接受/2 未定义。
    • 自定义错误链接失效,实际链接是这个one
    • 谢谢@EdouardMenayde,我修好了!
    【解决方案3】:

    以上答案都不适合我。 我能够让 phoenix 仅将 json 用于 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
    

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

    【讨论】:

      【解决方案4】:

      您可以用plug :accepts, ["json"] 覆盖router.ex 中的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
      

      它会起作用的。

      【讨论】:

        猜你喜欢
        • 2017-09-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-09-09
        • 1970-01-01
        • 2016-01-30
        • 2016-05-03
        相关资源
        最近更新 更多