Running into a problem with Phoenix when a user attempts to hit an API route that doesn't exist. Phoenix appears to be looking to render "404.html" by default, resulting in a catch all render function being called (which returns a map) which then results in an error because Phoenix is attempting to render JSON as HTML.
** (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
This is the default render function that is ultimately being called:
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
I have seen "set_format" solution that was in a previous question (here: https://stackoverflow.com/a/39189452) and, as the user states, this does feel a bit hacky, though it does appear to work.
I am also aware that I could just specify a render function that accepts 404.html but that also feels like a bit more of a bandaid than I would like.
My ultimate goal is to get Phoenix to not want to render 404.html, rather I would like to either arbitrarily specify the template, or at the least, tell Phoenix it should look for 404.json instead. Ideally, the solution would be application wide.