skip to Main Content

Laravel doesn’t log 404 errors by default. I want to change this behavior.

Most guides say to log it manually in the following block :

public function register(): void
{
    $this->reportable(function (Throwable $e) {
        // Handle 404 here
    });
}

but it seems like 404 exceptions don’t even trigger this method for some reason.

Doing the following technically works but it’s tedious to put everywhere I need it :

try {
     $model = User::findOrFail(99999);
} catch (ModelNotFoundException $e) {
     Log::error($e);
     throw $e;
}

I’m using Laravel 10.

What am I doing wrong ?

2

Answers


  1. Here’s why the first approach wasn’t working as expected and better ways to handle 404 logging in Laravel 10.

    Understanding the Issue

    The reportable method within the AppExceptionsHandler class is primarily designed to report exceptions for error tracking services, not specifically for logging every 404. This is why you weren’t seeing the effect you expected.

    Recommended Approaches

    Here’s how to effectively log 404 errors in Laravel 10:

    1. Custom Exception Handler Middleware

    Create a middleware (e.g., LogNotFoundRequests.php)

    <?php
    
    namespace AppHttpMiddleware;
    
    use Closure;
    use IlluminateHttpRequest;
    use SymfonyComponentHttpKernelExceptionNotFoundHttpException;
    use IlluminateSupportFacadesLog;
    
    class LogNotFoundRequests
    {
        public function handle(Request $request, Closure $next)
        {
            $response = $next($request);
    
            if ($response->status() === 404) {
                Log::error('404 Not Found: ' . $request->path());
            }
    
            return $response;
        }
    }
    

    Register the middleware in your appHttpKernel.php file. Add it to either your global middleware stack or a specific route group.

    1. Event Listener

    Create an event listener (e.g., LogNotFoundException.php)

    <?php
    
    namespace AppListeners;
    
    use IlluminateContractsQueueShouldQueue;
    use IlluminateQueueInteractsWithQueue;
    use IlluminateSupportFacadesLog;
    use SymfonyComponentHttpKernelExceptionNotFoundHttpException;
    
    class LogNotFoundException
    {
        public function handle(NotFoundHttpException $event)
        {
            Log::error('404 Not Found: ' . $event->getRequest()->path());
        }
    }
    

    Register the listener in your AppProvidersEventServiceProvider.php file:

    protected $listen = [
        // ... other events
        NotFoundHttpException::class => [
            LogNotFoundException::class,
        ],
    ];
    

    Choosing a Method

    Middleware: Good for simple, direct logging of the request path.
    Event Listener: Offers more flexibility if you want more elaborate error handling, such as passing data to other systems or creating custom log messages.

    Why Avoid try-catch Blocks

    Manually adding try-catch blocks with ModelNotFoundException everywhere is less ideal because:

    Repetition: It creates unnecessary code duplication.
    Limited Control: It doesn’t let you easily customize log messages or log levels.

    Login or Signup to reply.
  2. You can try with stopIgnoring method.

    https://laravel.com/docs/10.x/errors#ignoring-exceptions-by-type

    use IlluminateDatabaseEloquentModelNotFoundException;
     
    /**
     * Register the exception handling callbacks for the application.
     */
    public function register(): void
    {
        $this->stopIgnoring(ModelNotFoundException::class);
     
        // ...
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search