I’m learning Phoenix and developing a small app that serves both HTML and JSON content. I’m able to render the controller response based on the request. Everything works well except for any exceptions raised in router plugs, such as Phoenix.Router.NoRouteError
or Plug.CSRFProtection.InvalidCSRFTokenError
, which always return an HTML response.
I found out that I can use Plug.ErrorHandler
in Router to solve my problem:
defmodule AppWeb.Router do
use AppWeb, :router
use Plug.ErrorHandler
@impl Plug.ErrorHandler
def handle_errors(conn, %{kind: _kind, reason: _reason, stack: _stack}) do
headers = Enum.into(conn.req_headers, %{})
if headers["content-type"] == "application/json" do
body = AppWeb.Error.ErrorJSON.render("#{conn.status}.json", %{})
json(conn, body)
else
body = AppWeb.Error.ErrorHTML.render("#{conn.status}.html", %{})
html(conn, body)
end
end
Since I’m new to Phoenix, I’m not confident this is the only or best way to solve the the problem. Hence, my question is: How can I render errors/exceptions in router plugs based on the request’s content type?
Thanks,