【问题标题】:Setting up custom response for exception in Phoenix Application在 Phoenix 应用程序中为异常设置自定义响应
【发布时间】:2015-05-29 18:49:53
【问题描述】:

我用 ecto 编写 phoenix 应用程序并在测试中有以下 sn-p

{:ok, data} = Poison.encode(%{email: "nonexisting@user.com", password: "mypass"})

conn()
|> put_req_header("content-type", "application/json")
|> put_req_header("accept", "application/json")
|> post(session_path(@endpoint, :create), data)
> json_response(:not_found) == %{}

这会引发 Ecto.NoResultsError

我有这个定义

defimpl Plug.Exception, for: Ecto.NoResultsError do
  def status(_exception), do: 404
end

但测试仍然抛出 Ecto.NoResultsError, Any pointers?

【问题讨论】:

    标签: elixir phoenix-framework ecto


    【解决方案1】:

    让我们考虑一下它是如何在每个环境中工作的。

    • :prod中,默认是渲染错误页面,所以你应该会看到YourApp.ErrorView渲染的带有状态码的页面;

    • :dev 中,默认显示调试页面,因为大多数时候您在构建代码时都会出错。如果你想看到实际呈现的错误页面,你需要在你的config/dev.exs中设置debug_errors: false

    • :test 中,它像生产环境一样工作,但是因为您是从测试中调用应用程序,所以如果您的应用程序崩溃,您的测试也会崩溃。我们正在对未来的版本进行改进,您应该可以编写如下内容:

      assert_raise Ecto.NoResultsError, fn ->
        get conn, "/foo"
      end
      {status, headers, body} = sent_response(conn)
      assert status == 404
      assert body =~ "oops"
      

    【讨论】:

    • 嗨@josé-valim,这个有什么进展吗?现在是否可以在不先使用 assert_raise 的情况下断言状态?谢谢!
    • 现在已经改进了,见Leo Nikkilä的回答。
    【解决方案2】:

    Phoenix 1.1.0 引入了Phoenix.ConnTest.assert_error_sent/2,让测试类似案例变得更加容易。

    来自the documentation

    断言错误已被包装并以给定状态发送。

    对于测试您期望引发错误并将响应包装在 HTTP 状态中的操作很有用,内容通常由您的 MyApp.ErrorView 呈现。

    使用示例:

    assert_error_sent :not_found, fn ->
      get conn(), "/users/not-found"
    end
    
    response = assert_error_sent 404, fn ->
      get conn(), "/users/not-found"
    end
    assert {404, [_h | _t], "Page not found"} = response
    

    【讨论】:

      猜你喜欢
      • 2016-09-24
      • 1970-01-01
      • 1970-01-01
      • 2018-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-09
      • 1970-01-01
      相关资源
      最近更新 更多