From 6e7fc11ee2b714348415c61ae587bf7039bb580f Mon Sep 17 00:00:00 2001 From: catch <catch@35733.no-reply.drupal.org> Date: Mon, 16 Nov 2020 17:39:18 +0000 Subject: [PATCH] Issue #2949419 by mfb, vsujeetkumar, gapple, Hardik_Patel_12, neclimdul, dawehner, Sam152, xjm, alexpott: Pass the raw exception to logger implementations --- core/includes/errors.inc | 26 ++++++++++--------- core/includes/update.inc | 5 ++-- .../FinalExceptionSubscriber.php | 3 +-- core/lib/Drupal/Core/Utility/Error.php | 3 ++- core/modules/dblog/src/Logger/DbLog.php | 4 +-- .../Tests/Core/Error/DrupalLogErrorTest.php | 1 + 6 files changed, 22 insertions(+), 20 deletions(-) diff --git a/core/includes/errors.inc b/core/includes/errors.inc index 23ed7d4bb788..62179edf63ce 100644 --- a/core/includes/errors.inc +++ b/core/includes/errors.inc @@ -79,6 +79,7 @@ function _drupal_error_handler_real($error_level, $message, $filename, $line) { 'severity_level' => $severity_level, 'backtrace' => $backtrace, '@backtrace_string' => (new \Exception())->getTraceAsString(), + 'exception' => NULL, ], $recoverable || $to_string); } // If the site is a test site then fail for user deprecations so they can be @@ -133,10 +134,12 @@ function error_displayable($error = NULL) { * Logs a PHP error or exception and displays an error page in fatal cases. * * @param $error - * An array with the following keys: %type, @message, %function, %file, - * %line, @backtrace_string, severity_level, and backtrace. All the parameters - * are plain-text, with the exception of @message, which needs to be an HTML - * string, and backtrace, which is a standard PHP backtrace. + * An array with the following keys: %type, @message, %function, %file, %line, + * @backtrace_string, severity_level, backtrace, and exception. All the + * parameters are plain-text, with the exception of @message, which needs to + * be an HTML string, backtrace, which is a standard PHP backtrace, and + * exception, which is the exception object (or NULL if the error is not an + * exception). * @param bool $fatal * TRUE for: * - An exception is thrown and not caught by something else. @@ -146,13 +149,12 @@ function error_displayable($error = NULL) { function _drupal_log_error($error, $fatal = FALSE) { $is_installer = InstallerKernel::installationAttempted(); - // Remove 'severity_level' as is not a valid replacement for t(). - $severity = $error['severity_level']; - unset($error['severity_level']); - - // Backtrace array is not a valid replacement value for t(). + // Backtrace, exception and 'severity_level' are not valid replacement values + // for t(). $backtrace = $error['backtrace']; - unset($error['backtrace']); + $exception = $error['exception']; + $severity = $error['severity_level']; + unset($error['backtrace'], $error['exception'], $error['severity_level']); // When running inside the testing framework, we relay the errors // to the tested site by the way of HTTP headers. @@ -167,10 +169,10 @@ function _drupal_log_error($error, $fatal = FALSE) { // installer. if (\Drupal::hasService('logger.factory')) { try { - // Provide the PHP backtrace to logger implementations. Add + // Provide the PHP backtrace and exception to logger implementations. Add // 'severity_level' to the context to maintain BC and allow logging // implementations to use it. - \Drupal::logger('php')->log($severity, '%type: @message in %function (line %line of %file) @backtrace_string.', $error + ['backtrace' => $backtrace, 'severity_level' => $severity]); + \Drupal::logger('php')->log($severity, '%type: @message in %function (line %line of %file) @backtrace_string.', $error + ['backtrace' => $backtrace, 'exception' => $exception, 'severity_level' => $severity]); } catch (\Exception $e) { // We can't log, for example because the database connection is not diff --git a/core/includes/update.inc b/core/includes/update.inc index bea0c861e37a..d5818d005aaa 100644 --- a/core/includes/update.inc +++ b/core/includes/update.inc @@ -231,8 +231,7 @@ function update_do_one($module, $number, $dependency_map, &$context) { watchdog_exception('update', $e); $variables = Error::decodeException($e); - unset($variables['backtrace']); - unset($variables['severity_level']); + unset($variables['backtrace'], $variables['exception'], $variables['severity_level']); $ret['#abort'] = ['success' => FALSE, 'query' => t('%type: @message in %function (line %line of %file).', $variables)]; } } @@ -299,7 +298,7 @@ function update_invoke_post_update($function, &$context) { watchdog_exception('update', $e); $variables = Error::decodeException($e); - unset($variables['backtrace']); + unset($variables['backtrace'], $variables['exception']); $ret['#abort'] = [ 'success' => FALSE, 'query' => t('%type: @message in %function (line %line of %file).', $variables), diff --git a/core/lib/Drupal/Core/EventSubscriber/FinalExceptionSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/FinalExceptionSubscriber.php index a2a09ecf54c9..87d716932296 100644 --- a/core/lib/Drupal/Core/EventSubscriber/FinalExceptionSubscriber.php +++ b/core/lib/Drupal/Core/EventSubscriber/FinalExceptionSubscriber.php @@ -93,8 +93,7 @@ public function onException(ExceptionEvent $event) { $error = $this->simplifyFileInError($error); - unset($error['backtrace']); - unset($error['severity_level']); + unset($error['backtrace'], $error['exception'], $error['severity_level']); if (!$this->isErrorLevelVerbose()) { // Without verbose logging, use a simple message. diff --git a/core/lib/Drupal/Core/Utility/Error.php b/core/lib/Drupal/Core/Utility/Error.php index 092f7626e210..306486ed7a56 100644 --- a/core/lib/Drupal/Core/Utility/Error.php +++ b/core/lib/Drupal/Core/Utility/Error.php @@ -71,6 +71,7 @@ public static function decodeException($exception) { 'severity_level' => static::ERROR, 'backtrace' => $backtrace, '@backtrace_string' => $exception->getTraceAsString(), + 'exception' => $exception, ]; } @@ -86,7 +87,7 @@ public static function decodeException($exception) { public static function renderExceptionSafe($exception) { $decode = static::decodeException($exception); $backtrace = $decode['backtrace']; - unset($decode['backtrace']); + unset($decode['backtrace'], $decode['exception']); // Remove 'main()'. array_shift($backtrace); diff --git a/core/modules/dblog/src/Logger/DbLog.php b/core/modules/dblog/src/Logger/DbLog.php index 5933e222810c..4207a5c9db09 100644 --- a/core/modules/dblog/src/Logger/DbLog.php +++ b/core/modules/dblog/src/Logger/DbLog.php @@ -53,8 +53,8 @@ public function __construct(Connection $connection, LogMessageParserInterface $p * {@inheritdoc} */ public function log($level, $message, array $context = []) { - // Remove any backtraces since they may contain an unserializable variable. - unset($context['backtrace']); + // Remove backtrace and exception since they may contain an unserializable variable. + unset($context['backtrace'], $context['exception']); // Convert PSR3-style messages to \Drupal\Component\Render\FormattableMarkup // style, so they can be translated too in runtime. diff --git a/core/tests/Drupal/Tests/Core/Error/DrupalLogErrorTest.php b/core/tests/Drupal/Tests/Core/Error/DrupalLogErrorTest.php index a867cd196b0a..40103f08abba 100644 --- a/core/tests/Drupal/Tests/Core/Error/DrupalLogErrorTest.php +++ b/core/tests/Drupal/Tests/Core/Error/DrupalLogErrorTest.php @@ -35,6 +35,7 @@ public function testFatalExitCode() { '@backtrace_string' => 'backtrace', 'severity_level' => 0, 'backtrace' => [], + 'exception' => NULL, ]; _drupal_log_error($error, TRUE); EOT; -- GitLab