Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is my Laravel 11 exception handler not working?

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.)

enter image description here

(Using barryvdh/laravel-debugbar in this screenshot)

like image 280
Phil Tune Avatar asked Sep 06 '25 19:09

Phil Tune


1 Answers

Update (thanks @Olivier):

Laracasts forum answered this wonderfully: https://laracasts.com/discuss/channels/laravel/how-to-catch-a-policy-response-exception


My Original:

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 enter image description here

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();
like image 76
Phil Tune Avatar answered Sep 09 '25 20:09

Phil Tune