Error Handling
App Errors
Generally, we will use :info for 4XX status codes and :error or :fatal for 5XX errors.
| errors | status_code | level | description |
|---|---|---|---|
| UnauthorizedError | 401 | :info | requester not authorized to request the resource |
| NotFoundError | 404 | :info | request valid but cannot find the resource requested |
| ValidationError | 422 | :info | request valid and understood, but could not process the request. To allow us to automatically set tags in Sentry with is_validation: true |
| UnprocessableContentError | 422 | :info | request valid and understood, but could not process the request |
| InternalServerError | 500 | :error | request valid but server cannot execute it |
| UnimplementedError | 501 | :error | internal error for devs |
All errors extend a custom BaseError
BaseErrorthen extends Ruby'sStandardErrorclass- This provides it the standard error behaviours in Ruby
Why does ValidationError and UnprocessableContentError have the same status codes?
Right now as of 5 Aug, every manager raises UnprocessableContentError whenever validation fails.
UnprocessableContentError can be used elsewhere, for example, when a user does not have a Careers::UserProfile, but is trying to make an authenticated request.
This breaks single responsibility.
Why do we raise ValidationErrors?
It's important to have visibility where users are having trouble with in our system.
One place we can get visibility is when validations fail.
For example, if we see hundreds of validation errors raised in Identities::Users::CreateManager
- we will know that something is wrong with our sign up process and we should review it.
- Since we are recording errors, it is easy to measure impact of the fix.
- If there was a huge reduction of validation errors
Identities::Users::CreateManager, we know that the fix was in the right direction. - Otherwise, the "fix" did not solve the problem for the users.
- If there was a huge reduction of validation errors
Where does Sentry fit in?
We plug sentry into the Errors::BaseError.
All our custom app errors must extend BaseError.
- Think of it like an "interface" for all types of app errors will call
See in the diagram that every {Some}Error points to BaseError
Important Sentry Configurations
We are raising UnprocessableContentError (422) whenever validation fails. Should we report this error as an actual error in Sentry? Or should we be raising it as an "info"?
What's the point of raising errors during validations?
- So we know where users are messing up.
- This provides us clues if our forms/ux is too complex for users to understand.
- It's not an error, but rather providing us information that users are failing validations in a single request
- And that request, is most likely linked to the a form (i.e. POST request)
Sentry provides the following error levels from their docs
:fatal:error:warning:log:info:debug