首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >强制Phoenix呈现JSON错误

强制Phoenix呈现JSON错误
EN

Stack Overflow用户
提问于 2020-02-25 07:03:46
回答 2查看 1.4K关注 0票数 1

当用户尝试访问不存在的API路由时,会遇到Phoenix的问题。Phoenix似乎希望在默认情况下呈现"404.html“,这会导致调用catch all render函数(该函数返回一个地图),然后导致错误,因为Phoenix试图将JSON呈现为HTML。

代码语言:javascript
复制
** (UndefinedFunctionError) function Phoenix.HTML.Safe.to_iodata/1 is undefined (module Phoenix.HTML.Safe is not available)
        Phoenix.HTML.Safe.to_iodata(%{error: %{errors: ["An internal error has occurred. Our team has been notified."], message: "Internal Error"}})
        (phoenix) lib/phoenix/controller.ex:729: Phoenix.Controller.__put_render__/5
        (phoenix) lib/phoenix/endpoint/render_errors.ex:77: Phoenix.Endpoint.RenderErrors.instrument_render_and_send/5
        (phoenix) lib/phoenix/endpoint/render_errors.ex:62: Phoenix.Endpoint.RenderErrors.__catch__/5
        (phoenix) lib/phoenix/endpoint/cowboy2_handler.ex:42: Phoenix.Endpoint.Cowboy2Handler.init/4

这是最终要调用的默认呈现函数:

代码语言:javascript
复制
  def render(code, _assigns) do
    Logger.error("Error handler requested #{inspect code}. Please add support for that.")

    %{
      error: %{
        message: "Internal Error",
        errors: ["An internal error has occurred. Out team has been notified."]
      }
    }
  end

我见过前一个问题中的"set_format“解决方案(这里:https://stackoverflow.com/a/39189452),正如用户所说,这确实感觉有点老生常谈,尽管它看起来确实有效。

我还意识到,我可以只指定一个接受404.html的呈现函数,但这感觉也比我想要的更像是一个创可贴。

我的最终目标是让Phoenix不想呈现404.html,相反,我想随意指定模板,或者至少告诉Phoenix它应该寻找404.json。理想情况下,解决方案应该是应用程序范围的。

EN

回答 2

Stack Overflow用户

发布于 2020-02-26 00:01:24

您的路由器只是一个插头。您可以使用与Plug.Router或任何插件相同的方式处理错误。在下面的示例代码中,可以随意将MyAppWeb替换为您的web模块的名称。

代码语言:javascript
复制
defmodule MyAppWeb.Router do
  use MyAppWeb, :router
  use Plug.ErrorHandler  #<-- Add this line

  # and implement the callback handle_errors/2
  defp handle_errors(conn, %{reason: %Phoenix.Router.NoRouteError{message: message}}) do
    conn |> json(%{error: message}) |> halt()
  end

  defp handle_errors(conn, _) do
    conn |> json(%{error: "unknown"}) |> halt()
  end

  ...
end

请注意,您可以调用控制器可用的所有函数,因为Phoenix.Controller是在import MyAppWeb, :router时导入的。您可以在模块MyAppWeb的源代码中看到这一点,请注意宏__using__/1和函数router/0

票数 2
EN

Stack Overflow用户

发布于 2020-07-10 19:25:47

您应该将您的端点配置为将错误呈现为json:

代码语言:javascript
复制
config :the_app, TheApp.Endpoint,
  render_errors: [view: TheApp.ErrorView, accepts: ~w(json), layout: false]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60385212

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档