4

I'd like to know if it's possible to override the application exception handler class in Laravel 5 without extending it to another class.

Maybe a better way of saying it is that I'd like it so that not App\Exceptions\Handler will be called on an exception but one of my own handlers.

Thanks in advance.

frietkot
  • 891
  • 12
  • 28
  • Yeah, its possible. depends on the particular exception you wish to override – Emeka Mbah Aug 11 '15 at 07:12
  • I wish to override the entire exceptionhandler :) – frietkot Aug 11 '15 at 07:29
  • hmm... wondering why you wanna to do that, but guess you have your reason. One thing is.. if you mess up the handler, you might end up having blank pages when application throws an error. How about completely customizing `App\Exceptions\Handler` ? Must you keep the class file elsewhere? – Emeka Mbah Aug 11 '15 at 07:33
  • Haha, yes, I have my reasons;) (Mainly that I'm developing an inhouse laravel cms and I'd like to create something like the old 'whoops' error handler from l4). But extending App\Exception\Handler is not an option, I'd like it so that when I register my service provider, my custom handler will be called instead of the app exception handler. – frietkot Aug 11 '15 at 07:40
  • 3
    Okay. That's a good reason, Laravel registers `App\Exception\Handler'` in `bootstrap\app.php` like so `$app->singleton( Illuminate\Contracts\Debug\ExceptionHandler::class, App\Exceptions\Handler::class );` so you could look for a way of overriding it in your cms package or you could manually replace it which is more like a hack – Emeka Mbah Aug 11 '15 at 07:49

1 Answers1

3

As mentioned before by Digitlimit here Laravel ships with default ExceptionHandler which can be overwritten. There's two ways you can do so:

Adjusting the implemented ExceptionHandler

Laravel 5.8 ships with a default ExceptionHandler implemented in app/Exceptions/Handler.php. This class extends from Illuminate\Foundation\Exceptions\Handler which is the actual Laravel implementation of the Illuminate\Contracts\Debug\ExceptionHandler interface. By removing the parent class and implementing the interface yourself you could do all the custom exception handling you'd like. I've included a small example implementation of the Handler class at the end of my answer.

Registering a new ExceptionHandler

Another way of implementing a custom ExceptionHandler is to overwrite the default configuration which can be found in bootstrap/app.php. In order to overwrite the handler specified by Larvel simply register a singleton for the Illuminate\Contracts\Debug\ExceptionHandler::class abstraction after the default one like so.

# Laravel default
$app->singleton(
    Illuminate\Contracts\Debug\ExceptionHandler::class,
    App\Exceptions\Handler::class
);

# My custom handler
$app->singleton(
    Illuminate\Contracts\Debug\ExceptionHandler::class,
    App\Exceptions\MyHandler::class
);

The result of this is that App\Exceptions\MyHandler is called in case an exception is thrown and App\Exceptions\Handler is skipped altogether.

Example ExceptionHandler

It case it's useful I've included a small example of a custom ExceptionHandler to give a global idea of it's possibilities.

namespace App\Exceptions;

use Exception;
use Illuminate\Contracts\Debug\ExceptionHandler;
use Illuminate\Support\Facades\Log;
use Symfony\Component\Console\Application;

class Handler implements ExceptionHandler
{
    public function report(Exception $e)
    {
        Log::debug($e->getMessage());
    }

    public function shouldReport(Exception $e)
    {
        return true;
    }

    public function render($request, Exception $e)
    {
        return view('error.page');
    }

    public function renderForConsole($output, Exception $e)
    {
        (new Application)->renderException($e, $output);
    }
}
PtrTon
  • 3,705
  • 2
  • 14
  • 24