1 Overview
Whenever we have an application error, we want to respond with a JSONAPI-compliant errors payload. This way clients have a predictable response detailing information about the error.
We’ll also need a way to customize this payload. For instance, if a
NotAuthorized
error is raised, the response should have a 403
status
code. For other errors, we may want to render a helpful error message:
Correctly handling exceptions happens in graphiti-rails. Customizing the behavior based on error class happens in the RescueRegistry dependency.
1.1 Setup
Just make sure you have graphiti-rails installed:
And you’re all set!
1.1.1 Displaying Raw Errors
It can be useful to display the raw error as part of the JSON response -
but you probably don’t want to expose your stack trace to customers.
Let’s only show raw errors for the staging
environment:
Another common pattern is to only show raw errors when the user is privileged to see them:
When #show_detailed_exceptions?
returns true
, you’ll get the raw error class,
message, and backtrace in the JSON response.
2 Usage
2.1 Basic
Let’s register an error with a custom response code:
Now if we raise Errors::NotAuthorized
, the response code will be
403
.
Additional options:
See full documentation in the RescueRegistry README.
All controllers will inherit any registered exceptions from their parent. They can also add their own. In this example, FooError
will only throw a custom status code when thrown from FooController
:
2.2 Advanced
The final option register_exception
accepts is handler
. Here you can inject your own error handling class that customize RescueRegistry::ExceptionHandler
. For example:
If you would like to use the same custom handler for all errors, override default_exception_handler
:
3 Testing
This pattern of globally rescuing exceptions makes sense when running our live application…but during testing, we may want to raise real errors and bypass this rescue logic.
This is why we turn off error-handling during tests by default:
If you want to turn this on for an individual test (so you can test error codes, etc):