Here is test that I'm trying to get working again (it did on Phoenix 1.2):
alias MyApp.ErrorView
import Phoenix.View
# ..
test "render any error" do
assert render(ErrorView, "505.html", []) ==
"Internal server error"
assert render(ErrorView, "505.json", []) ==
%{error: "Internal server error", status: 500}
end
Error view looks like this:
defmodule MyApp.ErrorView do
use MyApp.Web, :view
# ...
def render("500.json", assigns) do
%{error: render("500.html", assigns), status: 500}
end
def render("500" <> _, _assigns) do
"Internal server error"
end
def template_not_found(<<_status::binary-size(3), format::binary>>, assigns) do
render("500" <> format, assigns)
end
def template_not_found(_template, assigns) do
render "500.html", assigns
end
end
I expect test to trigger template_not_found/2 function because there are no render for 505.json.
1) test render any error (MyApp.Tests.ErrorViewTest)
test/my_app/views/error_view_test.exs:41
** (FunctionClauseError) no function clause matching in MyApp.ErrorView.render/2
The following arguments were given to MyApp.ErrorView.render/2:
# 1
"505.html"
# 2
%{view_module: MyApp.ErrorView, view_template: "505.html"}
Attempted function clauses (showing 7 out of 7):
def render("404.json", assigns)
def render("404.html", %{reason: %Ecto.NoResultsError{}})
def render("404.html", _assigns)
def render("400.json", assigns)
def render("400.html", _assigns)
def render("500.json", assigns)
def render(<<"500"::binary(), _::binary()>>, _assigns)
code: assert render(ErrorView, "505.html", []) ==
stacktrace:
(my_app) lib/my_app/views/error_view.ex:4: MyApp.ErrorView.render/2
test/my_app/views/error_view_test.exs:42: (test)
Can you push a minimal app to a repo that reproduces the issue? From the provided code it looks like it should work as you describe. It would also be helpful if you could include your entire, exact ErrorView module
Full tests code:
defmodule MyApp.ErrorViewTest do
use MyApp.ConnCase, async: true
alias MyApp.ErrorView
import Phoenix.View
test "renders 404.html" do
assert render(ErrorView, "404.html", []) ==
"Page not found"
end
test "render 500.html" do
assert render(ErrorView, "500.html", []) ==
"Internal server error"
end
test "renders 404.json" do
assert render(ErrorView, "404.json", []) ==
%{
error: "Page not found",
status: 404
}
end
test "renders 404.json with ecto error" do
assigns = [reason: %Ecto.NoResultsError{}]
assert render(ErrorView, "404.json", assigns) ==
%{
error: "resource not found",
status: 404
}
end
test "render 500.json" do
assert render(ErrorView, "500.json", []) ==
%{
error: "Internal server error",
status: 500
}
end
test "render any error" do
assert render_to_string(ErrorView, "505.html", []) ==
"Internal server error"
assert render_to_string(ErrorView, "505.json", []) ==
%{error: "Internal server error", status: 500}
end
end
Full view code:
defmodule MyApp.ErrorView do
use MyApp.Web, :view
def render("404.json", assigns) do
%{error: render("404.html", assigns), status: 404}
end
def render("404.html", %{reason: %Ecto.NoResultsError{}}) do
"resource not found"
end
def render("404.html", _assigns) do
"Page not found"
end
def render("400.json", assigns) do
%{error: render("400.html", assigns), status: 400}
end
def render("400.html", _assigns) do
"bad request"
end
def render("500.json", assigns) do
%{error: render("500.html", assigns), status: 500}
end
def render("500" <> _, _assigns) do
"Internal server error"
end
def template_not_found(<<_status::binary-size(3), format::binary>>, assigns) do
render("500" <> format, assigns)
end
def template_not_found(_template, assigns) do
render "500.html", assigns
end
end
I can't recreate this using your view and test code. Are you sure that you aren't referencing an old view module, i.e. alias MyApp.ErrorView is in your code. Maybe you renamed this file/module to MyAppWEb.ErrorView and either kept the old file, or your _build contains the old module? Can you verify no old module/file exists, and if so, blow away build to be sure, and retry? Thanks!
Unfortunately, nothing helps:
_build entirelySearching 366 files for "ErrorView"
/Users/andrew/Projects/myapp-api/apps/myapp_api/lib/myapp_api/views/error_view.ex:
1: defmodule MyApp.ErrorView do
2 use MyApp.Web, :view
3
/Users/andrew/Projects/myapp-api/apps/myapp_api/test/myapp_api/views/error_view_test.exs:
1: defmodule MyApp.ErrorViewTest do
2 use MyApp.ConnCase, async: true
3: alias MyApp.ErrorView
4 import Phoenix.View
5
6 test "renders 404.html" do
7: assert render(ErrorView, "404.html", []) ==
8 "Page not found"
9 end
10
11 test "render 500.html" do
12: assert render(ErrorView, "500.html", []) ==
13 "Internal server error"
14 end
15
16 test "renders 404.json" do
17: assert render(ErrorView, "404.json", []) ==
18 %{
19 error: "Page not found",
..
24 test "renders 404.json with ecto error" do
25 assigns = [reason: %Ecto.NoResultsError{}]
26: assert render(ErrorView, "404.json", assigns) ==
27 %{
28 error: "resource not found",
..
32
33 test "render 500.json" do
34: assert render(ErrorView, "500.json", []) ==
35 %{
36 error: "Internal server error",
..
40
41 test "render any error" do
42: assert render(MyApp.ErrorView, "505.html", []) ==
43 "Internal server error"
44: assert render(MyApp.ErrorView, "505.json", []) ==
45 %{error: "Internal server error", status: 500}
46 end
10 matches across 2 files
I'll dig deeper and report in case I would find the root cause.
Just in case, view macro looks like this:
def view do
quote do
import Phoenix.View
import Phoenix.Controller, only: [view_module: 1]
import MyApp.Router.Helpers
@view_resource String.to_atom(Phoenix.Naming.resource_name(__MODULE__, "View"))
@doc "The resource name, as an atom, for this view"
def __resource__, do: @view_resource
end
end
And ConnCase:
defmodule MyApp.ConnCase do
use ExUnit.CaseTemplate
using do
quote do
use Phoenix.ConnTest
alias MyApp.Domain.Repo
import Ecto
import Ecto.Query, only: [from: 2]
import MyApp.Router.Helpers
import MyApp.ConnCase
@endpoint MyApp.Endpoint
end
end
end
Is it possible for your to extract these files into a minimal repo that replicates this? That would be super helpful to try to track this down. Thanks!
Closing for now as I'm not able to replicate. If you are able to provide a minimal repo that replicates this, please bump the issue. Thanks!
Most helpful comment
Is it possible for your to extract these files into a minimal repo that replicates this? That would be super helpful to try to track this down. Thanks!