-
-
Notifications
You must be signed in to change notification settings - Fork 141
feat(core)!: overhaul exception handling #1819
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 3.x
Are you sure you want to change the base?
Conversation
NeoIsRecursive
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One thing I was thinking about, and I might have missed, translations on the "built-in" error messages?
Really looking forward to using this 👌
That made me go through an unexpected clean-up rabbit hole! It's now implemented for HTML responses 👍 |
Supersedes #1629
Fixes #1619
This pull request attempts to properly fix the error handling to allow for more flexibility regarding how responses are returned when there are errors.
New features
Exception renderers
Previously, we had the rendering logic in our exception handler. The exception handler is now responsible for finding the right exception renderer to render an exception as a response.
Exception renderers implement the
ExceptionRendererinterface, which require acanRenderand arendermethod.We now provide a
JsonExceptionRendererand aHtmlExceptionRenderer, which check for theAcceptheader to decide whether they can be used. For now, the HTML renderer has priority because browsers send*/*as anAcceptvalue, but I feel like we should have the equivalent of awantsJsonand also use that as a heuristic.Users may now implement their own 404 or other error pages by implementing their own renderer:
Note that while used internally,
HttpRequestFailedis now also intended for userland usage. It's not always convenient to return a response (likeNotFound) for errors due to nesting or return types.The optional message that this exception accepts will be displayed in the error pages in production, too. When generating our own
HttpRequestFailedinternally, we use generic error messages and don't leak exception details.Exception page
I got rid of Whoops and implemented our own exception page (highly inspired by Laravel's design). It's not feature-complete, but it's a good basis with more features and quality of life that Whoops.
Note
Its front-end makes a lot of noise in the diff. It's in
packages/router/src/> Exceptions/local, so unless you want to review Vue stuff, you can ignore that. Also note that the distribution files must be built whenever a change is made to the front-end.ExceptionsConfigIt adds a convenient way to disable the default
LoggingExceptionReporter, instead of having to write a kernel boot event listener to remove it manually.It also contains the discovered exception reporters instead of the
AppConfig. They needed their own home.Breaking changes
Renamed
throwHttpExceptionsin testsThis feature was a bit of a work around the inability to catch exceptions in tests. The issue is that it introduced inconsistent behavior during tests and in production, and it was weird to reason about.
The new workaround is simply to catch exceptions during
HttpRouterTester#sendRequest. When an exception is thrown, the exception handler is manually called to render the response, which is passed down to theTestResponseHelper.Users that used
throwExceptions()manually before will need to adapt their tests.Removed
InvalidI removed
Invalidas a response. It felt out of place and made it hard to have proper code for HTML and JSON handling.Plus, its constructor expected "internal" properties (request, failed rules, failing class FQCN). Its logic is now in dedicated exception renderers when
ValidationFailedis thrown.Renamed
ExceptionProcessorandExceptionReporterI renamed swapped their names because it makes more sense:
The
ExceptionProcessoris responsible for processing exceptions. It's not discoverable, replacing it requires an initializer.The
ExceptionReporterclasses are discoverable userland classes meant for reporting exceptions. By default, we still offer aLoggingExceptionReporterwhich write exceptions in log files.It's a breaking change only if users implemented their own
ExceptionProcessor, which they have to rename now.Renamed
HasContextI renamed it to
ProvidesContext. I took the opportunity to give it a better name.To-dos
throwHttpExceptions