but I would like to just call something like render(conn, "401.json") and have it be handled in the lib/<myapp_web>/views/error_view.ex module as 404 and 500 errors are. I know this is what happens on Ecto.NoResultsError, the function render("404.json", conn) is called in error_view.ex. It looks like I can do it with a custom error from these docs: https://hexdocs.pm/phoenix/errors.html but I’m missing some details on how to do that. I’m not sure if that is the best way to DRY up my code anyways.
I use the fallback controller… and then just let the controller return {:error, :unauthorized } when needed - so the controller is nice and DRY
defmodule Myapp.Web.SomeController do
...
action_fallback(Myapp.Web.FallbackController)
def show(conn, params) do
user = SomeAuth.get_user(params)
if user do
render normal etc..
else
{:error, :unauthorized }
end
end
end
and fallback has:
defmodule Myapp.Web.FallbackController do
@moduledoc """
Translates controller action results into valid `Plug.Conn` responses.
See `Phoenix.Controller.action_fallback/1` for more details.
"""
use Myapp.Web, :controller
...
def call(conn, {:error, :unauthorized}) do
conn
|> put_status(:unauthorized)
|> render(Myapp.Web.ErrorView, "auth_required.json")
end
end
and the ErrorView has a
def render("auth_required.json", _assigns) do
%{error: "Unauthorized"}
end
Ok, I used your solution with a slight modification to the FallbackController in order to prevent the deprecation warning:
defmodule Myapp.Web.FallbackController do
@moduledoc """
Translates controller action results into valid `Plug.Conn` responses.
See `Phoenix.Controller.action_fallback/1` for more details.
"""
use Myapp.Web, :controller
...
def call(conn, {:error, :unauthorized}) do
conn
|> put_status(:unauthorized)
|> put_view(Myapp.Web.ErrorView)
|> render("auth_required.json")
end
end