Using Laravel 11, exception handling is moved to the bootstrap/app.php
file. I'm trying to catch AuthorizationException
and pass the user back to the dashboard with the 403 message:
// bootstrap/app.php
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Http\Request;
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
return Application::configure(basePath: dirname(__DIR__))
...
->withExceptions(function (Exceptions $exceptions) {
$exceptions->render(function (AuthorizationException $e, Request $request) {
return redirect()
->route('dashboard')
->withErrors($e->getMessage());
});
...
})
...
->create();
But it's not working. This logged in user is gated from seeing the /users
endpoint, but it's not being handled by my exception handler. They should be seeing their dashboard. (My .env
does show APP_DEBUG=true
.)
(Using barryvdh/laravel-debugbar
in this screenshot)
Laracasts forum answered this wonderfully: https://laracasts.com/discuss/channels/laravel/how-to-catch-a-policy-response-exception
Changed exception type-hint to just Throwable
to inspect whatever gets caught:
$exceptions->render(function (Throwable $e, Request $request) {
dd($e);
...
});
...and it looks like it skipped the AuthorizationException and passed a Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
Question now is "why?" Why do Laravel docs not give more detail about how to handle common exceptions? Anyways, it's solved, but others might have the same issue, so here's my fix:
<?php
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
return Application
::configure(basePath: dirname(__DIR__))
...
->withExceptions(function (Exceptions $exceptions) {
$exceptions->render(function (Throwable $e) {
if ( $e instanceof AccessDeniedHttpException ) {
/* This may be overly specific, but I want to handle other
potential AccessDeniedHttpExceptions when I come
across them */
if ( $e->getPrevious() instanceof AuthorizationException ) {
return redirect()
->route('dashboard')
->withErrors($e->getMessage());
}
}
});
})
->create();