defmodule MyApp.ErrorView do
use MyApp.Web, :view
def render("404.json", _assigns) do
json(%{error: "page not found"})
end
# infinite loop!!!
def render("404.html", assigns) do
render(__MODULE__, "404.html")
end
def render("500.json", assigns) do
json(%{error: "internal server error"})
end
# infinite loop!!!
def render("500.html", assigns) do
render(__MODULE__, "404.html")
end
end
The thing is that for html responses it enters an infinite loop when the 400 or 500 error occurs.
Why is that?
And what’s the exact signature of these functions supposed to be and how are they supposed to be called from a controller? I mean, should it be just def render("404", assigns)? Then this won’t be descriptive enough and also how would I distinguish between html and json and … whatever other format I have?
Take a very close look at the function head and the template in the render call. But how did you make it compile at all? According to the documentation there shouldn’t be a render/2 in a view, but only a render/3…
Well. I have already given an answer to your question as best as I am able to with the code you gave us. Also, it is hard to reason about a function that does not exist in the given context, so I had to assume, that it simply wraps Phoenix.View.render/3 with assigns beeing the empty list. But of course it could be, that you pull in render/2 from Phoenix.Controller, but that wouldn’t make much sense, since it requires a Plug.Conn as first argument, not an alias.
So my answer is based on assumptions.
If you gave the exact code that has the problem (and only that, the JSON related function heads are irrelevant to this problem), there were no need to assume anything.
@kaa.python, I believe you haven’t specified what you want to achieve.
I’m guessing here, but I assume what you want to achieve is to render a template named 404.html. If that is true, then what you need to do is to have a file in templates/error/404.html.eex and delete the render function on your ErrorView. You only need those functions if you don’t have any templates to render (therefore rendering a string or a json directly).
See the Phoenix guides for more info: The ErrorView.
Also, if I may give a suggestion, since you are asking for help/information, do help others to help you by giving the information they need. If you absolutely can’t give it, please give arguments and/or explanations on why you think the information you have given is enough. Simply saying “you don’t need them” or “that’s not the point” hardly helps.
def render("404.html", assigns) do
render(__MODULE__, "404.html")
end
The function body does call the function it’s in. If you want to call the template directly – and not the render function on the view module) – use render_template("foo.html", assigns). This is documented here: https://hexdocs.pm/phoenix/Phoenix.Template.html#module-rendering