TL;DR
I want to be able to do something like raise Plug.HTTPError, plug_status: 501, message: "Some optional message"
so that I can easily return helpful errors in a RESTful JSON API that I am working on.
The status code may change, and the message is optional.
I don’t want to have to have to create an exception for this because it comes up in every API I work on, so it makes sense (to me) to have a one-liner solution ready to go.
The Issue, and Why I Am Searching for a Solution
I am working on a RESTful JSON API using Phoenix, and am frequently dealing with the issue of having to abort a request for various reasons, e.g. 422
errors for client-side issues (like some input that is determined to be invalid at some point during the request), 501
errors for server-side issues (like we haven’t implemented an action for a request that contains a certain parameter), and so on.
This can happen at various stages of the request, for a variety of reasons. The conn
may or may not be available as part of the function call. But at some point it happens that:
- The request needs to be aborted with a certain HTTP status code,
- With a helpful error message, and
- This should be accomplished in a clean manner with minimal hoop-jumping.
How I’m currently solving the problem.
What I am currently doing is e.g. raise Plug.BadRequestError, plug_status: 501
. I’m using Plug.BadRequestError
since it is one of the few ready-to-use implementations of a plug exception defined in the Plug
library itself.
It works great. Now, in my ErrorJSON
module, I just have to add this:
def render(<<_status::binary-3>> <> ".json", %{reason: %{message: message}} = _assigns) do
%{errors: %{detail: message}}
end
And now, I can, in 1 line, from anywhere in the Phoenix application, raise an exception with any desired status code, and terminate the request quickly, easily, and cleanly, while showing a helpful message to the consumer of the API.
The Problem With My Solution
Obviously, the Plug.BadRequestError
is intended for a specific use case. Is there a better way to raise a generic exception? (I would strongly prefer not to have to litter each app with a new module for such a common (for me) task.)
Tell Me What You Think
Please let me know your thoughts on the situation.
I have thought that it may be nice to have a generic exception ready to use in the Plug
library for this (e.g. Plug.HTTPError
, or Plug.Error
or Plug.CustomError
).
If you have a better solution to this problem, I would be glad to hear it.