Should a handler set with set_error_handler()
terminate the script if fatal errors are reported. For instane E_USER_ERROR
or will this be handled anyway?
I have a application the registers a handler with monolog but trigger_error( '', E_USER_ERROR );
does not terminate the script.
the handler:
set_error_handler( function ($errno, $errstr, $errfile, $errline) {
// error was suppressed with the @-operator
if( 0 === error_reporting() ) {
return false;
}
switch($errno) {
default:
LOG->error( "Unknown error type: [$errno] $errstr", [ 'file' => $errfile, '@' => $errline ] );
break;
case E_USER_ERROR: // fall through
case E_ERROR: // fall through
case E_WARNING: // PHP Warnings are errors
LOG->error( $errstr, [ 'file' => $errfile, '@' => $errline ] );
break;
case E_USER_DEPRECATED:
case E_DEPRECATED:
LOG->error( "DEPRECATED $errstr", [ 'file' => $errfile, '@' => $errline ] );
break;
case E_USER_WARNING: // fall through
case E_NOTICE: // PHP Notices are warnings
LOG->warning( $errstr, [ 'file' => $errfile, '@' => $errline ] );
break;
case E_USER_NOTICE:
LOG->notice( $errstr, [ 'file' => $errfile, '@' => $errline ] );
break;
}
/* Don't execute PHP internal error handler */
return true;
} );
When you set a custom error handler using set_error_handler(), it allows you to intercept and handle different types of PHP errors. However, the behavior of the script after handling the error depends on how the handler is implemented.
In your case, your custom error handler does not stop script execution after handling an E_USER_ERROR or similar fatal errors (E_ERROR). This is why the script continues to execute even after a trigger_error('', E_USER_ERROR).
To terminate the script when a fatal error is encountered (like E_USER_ERROR), you need to explicitly terminate the script using exit() or die() inside your custom error handler. Here's how you can modify your handler to terminate the script:
set_error_handler(function ($errno, $errstr, $errfile, $errline) {
// error was suppressed with the @-operator
if (0 === error_reporting()) {
return false;
}
switch ($errno) {
default:
LOG->error("Unknown error type: [$errno] $errstr", ['file' => $errfile, '@' => $errline]);
break;
case E_USER_ERROR: // fall through
case E_ERROR: // fall through
case E_WARNING: // PHP Warnings are errors
LOG->error($errstr, ['file' => $errfile, '@' => $errline]);
// Default handler not called: terminate the script for fatal errors
exit(1);
case E_USER_DEPRECATED:
case E_DEPRECATED:
LOG->error("DEPRECATED $errstr", ['file' => $errfile, '@' => $errline]);
break;
case E_USER_WARNING: // fall through
case E_NOTICE: // PHP Notices are warnings
LOG->warning($errstr, ['file' => $errfile, '@' => $errline]);
break;
case E_USER_NOTICE:
LOG->notice($errstr, ['file' => $errfile, '@' => $errline]);
break;
}
/* Don't execute PHP internal error handler */
return true; });