How can I add a custom header to my error pages?

ErrorView is great for serving custom error pages, but what about manipulating headers? Is there a straightforward way of modifying the error response conn, without creating error-specific routes?

:wave:

I think you can do it by implementing a Plug.Exception protocol for your errors:

defimpl Plug.Exception, for: Your.Error do
  def status(_), do: 400 # or anything else
  def actions(_), do: []
end

More info: Phoenix.NotAcceptableError - How can I return an error instead of having the app just have an exception? - #2 by idi527

1 Like

I have no idea whether this approach is optimal, but this is what I ended up doing:

defmodule MyprojectWeb.Router do
  use Plug.ErrorHandler
  [...]
  def handle_errors(conn, %{reason: %{plug_status: 404}}), do: my_custom_handler(conn, "Page not found")
  def handle_errors(conn, %{reason: %{plug_status: 400}}), do: my_custom_handler(conn, "Invalid request")
  [any number of additional desired HTTP status code handlers]
  def handle_errors(conn, _), do: my_custom_handler(conn, "Internal server error")
end

As to individual status code handling, it looks like plug_status can take any of the following values:

400 Phoenix.ActionClauseError
400 Phoenix.MissingParamError
406 Phoenix.NotAcceptableError
400 Phoenix.Router.MalformedURIError
404 Phoenix.Router.NoRouteError
400 Plug.BadRequestError
403 Plug.CSRFProtection.InvalidCSRFTokenError
403 Plug.CSRFProtection.InvalidCrossOriginRequestError
400 Plug.Conn.InvalidQueryError
400 Plug.Parsers.BadEncodingError
400 Plug.Parsers.ParseError
413 Plug.Parsers.RequestTooLargeError
415 Plug.Parsers.UnsupportedMediaTypeError
400 Plug.Router.MalformedURIError
400 Plug.Static.InvalidPathError
408 Plug.TimeoutError