Pragmatism in the real world

Overriding Slim 3's error handling

Slim 3 registers two error handers:

This means that if you want to override the default error handlers, you need to override both error handlers with your own code.

Each error handler is a callable. The signatures are:

  • errorHandler: function ($request, $response, $exception)
  • phpErrorHandler: function ($request, $response, $error)

To override a error handler, simply register a new callable with the Container:

$container = $app->getContainer();

$container['errorHandler'] = function ($container) {
    return function ($request, $response, $exception) use ($container) {
        // retrieve logger from $container here and log the error
        $response->getBody()->rewind();
        return $response->withStatus(500)
                        ->withHeader('Content-Type', 'text/html')
                        ->write("Oops, something's gone wrong!");
    };
};

$container['phpErrorHandler'] = function ($container) {
    return function ($request, $response, $error) use ($container) {
        // retrieve logger from $container here and log the error
        $response->getBody()->rewind();
        return $response->withStatus(500)
                        ->withHeader('Content-Type', 'text/html')
                        ->write("Oops, something's gone wrong!");
    };
};

If you don’t want to repeat yourself, you can register the `phpErrorHandler` like this:

$container['phpErrorHandler'] = function ($container) {
    return $container['errorHandler'];
};

Note that you can register any PHP callable, so a class with an __invoke() method also works.

Handling PHP notices

As an aside, Slim 2’s error handler catches PHP notices for you (which can be infuriating or very useful!). Slim 3 doesn’t do this by default, so if you want to catch PHP notices then you need to register your own error handler like this:

set_error_handler(function ($severity, $message, $file, $line) {
    if (!(error_reporting() & $severity)) {
        // This error code is not included in error_reporting, so ignore it
        return;
    }
    throw new \ErrorException($message, 0, $severity, $file, $line);
});

That’s all there is to it.

9 thoughts on “Overriding Slim 3's error handling

  1. Its really Helpful :)

    dear Rob Allen, Is there anything wrong in doing like this ? If I don't want to repeat.

    $myErrorHandler = function ($container) {

    };

    $container['phpErrorHandler'] = $myErrorHandler;
    $container['errorHandler'] = $myErrorHandler;

      1. Hi @Rob,

        Style 4 and 5, mentioned below, is creating problem. All other works cool.
        Is it due to the getter and setter mechanism, implementation behaviour of $container['key'] within Slim ?

        If not, I need more dig on PHP Basics !!!

        //============= Style #1 =============
        $myErrorHandler = function ($container) {

        };

        $container['phpErrorHandler'] = $myErrorHandler;
        $container['errorHandler'] = $myErrorHandler;

        // WORKS COOL :)

        //============= Style #2 =============
        $container['phpErrorHandler'] = $container['errorHandler'] = function ($container) {

        };

        // WORKS COOL :)

        //============= Style #3 =============
        $container['errorHandler'] = $container['phpErrorHandler'] = function ($container) {

        };

        // WORKS COOL :)

        //============= Style #4 =============
        $container['phpErrorHandler'] = function ($container) {

        };

        $container['errorHandler'] = $container['phpErrorHandler'];

        // NOT WORKING :(
        // Warning: Missing argument 2 for {closure}()
        // Warning: Missing argument 3 for {closure}()

        //============= Style #5 =============
        $container['errorHandler'] = function ($container) {

        };

        $container['phpErrorHandler'] = $container['errorHandler'];

        // NOT WORKING :(
        // Warning: Missing argument 2 for {closure}()
        // Warning: Missing argument 3 for {closure}()

        Thank You :)

  2. About notices, if I understand this code correctly, when "catching" a notice, an ErrorException will be thrown which will lead to stopping code execution?

      1. What if we want simple error handler to have logged all notice, error, warnings and stop code only when there is error/exception?

Comments are closed.