Overriding Slim 3's error handling
Slim 3 registers two error handers:
- errorHandler to trap PHP Exceptions
- phpErrorHandler to trap PHP 7 Errors
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.
Thanks for the share
Really helpful thanks, particularly the PHP 7 stuff.
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;
Nope. That should work.
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 :)
About notices, if I understand this code correctly, when "catching" a notice, an ErrorException will be thrown which will lead to stopping code execution?
Yes – if you add the error_handler.
What if we want simple error handler to have logged all notice, error, warnings and stop code only when there is error/exception?