diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index 87b0332..6fa4809 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -962,6 +962,17 @@ function _drupal_error_handler($error_level, $message, $filename, $line, $contex } /** + * Extends the custom PHP error handling. + */ +function _drupal_php_shutdown_error_handler() { + require_once __DIR__ . '/errors.inc'; + _drupal_php_shutdown_error_handler_real(); +} + +// Set the Drupal custom error handler. (requires config()) +drupal_register_shutdown_function('_drupal_php_shutdown_error_handler'); + +/** * Provides custom PHP exception handling. * * Uncaught exceptions are those not enclosed in a try/catch block. They are diff --git a/core/includes/errors.inc b/core/includes/errors.inc index 4065408..0c94a96 100644 --- a/core/includes/errors.inc +++ b/core/includes/errors.inc @@ -80,6 +80,53 @@ function _drupal_error_handler_real($error_level, $message, $filename, $line, $c } /** + * Extends the custom PHP error handling to handle error types that cannot be + * captured by the standard PHP error handler. + */ +function _drupal_php_shutdown_error_handler_real() { + // As defined at http://php.net/manual/en/function.set-error-handler.php + // following error types cannot be handled by the custom defined error handler + // callback. + $error_types = array( + E_ERROR, + E_CORE_ERROR, + E_CORE_WARNING, + E_COMPILE_ERROR, + E_COMPILE_WARNING, + ); + + // Check if an error was thrown and it's one that can only be captured by a + // shutdown function. + if (!($error = error_get_last()) || !in_array($error['type'], $error_types)) { + return; + } + + $error_level = $error['type']; + + $types = drupal_error_levels(); + list($severity_msg, $severity_level) = $types[$error_level]; + + if (!function_exists('filter_xss_admin')) { + require_once __DIR__ . '/common.inc'; + } + + // We treat recoverable errors as fatal. + _drupal_log_error(array( + '%type' => isset($types[$error_level]) ? $severity_msg : 'Unknown error', + // The standard PHP error handler considers that the error messages + // are HTML. We mimick this behavior here. + '!message' => filter_xss_admin($error['message']), + // The function info is not provided. + '%function' => '', + '%file' => $error['file'], + '%line' => $error['line'], + 'severity_level' => $severity_level, + // There is not useful backtrace in this case. + 'backtrace' => array(), + ), TRUE); +} + +/** * Determines whether an error should be displayed. * * When in maintenance mode or when error_level is ERROR_REPORTING_DISPLAY_ALL,