summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Pott2014-02-12 15:58:00 (GMT)
committerAlex Pott2014-02-12 15:58:00 (GMT)
commitd861851e3d470b9edc895e516c29d8d1e44f9948 (patch)
tree24070abdddb57eda18f4249a00df18572c0c7a65
parent7ce03d6bb4ca6de9e68386e2980e69b9857bdab6 (diff)
Issue #2188523 by sun: ExceptionController does not respect configured system.logging:error_level (verbose backtrace).
-rw-r--r--core/lib/Drupal/Core/Controller/ExceptionController.php31
-rw-r--r--core/lib/Drupal/Core/Utility/Error.php52
2 files changed, 81 insertions, 2 deletions
diff --git a/core/lib/Drupal/Core/Controller/ExceptionController.php b/core/lib/Drupal/Core/Controller/ExceptionController.php
index c8da4bc..d79567c 100644
--- a/core/lib/Drupal/Core/Controller/ExceptionController.php
+++ b/core/lib/Drupal/Core/Controller/ExceptionController.php
@@ -317,13 +317,40 @@ class ExceptionController extends HtmlControllerBase implements ContainerAwareIn
$class = 'error';
// If error type is 'User notice' then treat it as debug information
- // instead of an error message, see dd().
+ // instead of an error message.
+ // @see debug()
if ($error['%type'] == 'User notice') {
$error['%type'] = 'Debug';
$class = 'status';
}
- drupal_set_message(t('%type: !message in %function (line %line of %file).', $error), $class);
+ // Attempt to reduce verbosity by removing DRUPAL_ROOT from the file path
+ // in the message. This does not happen for (false) security.
+ $root_length = strlen(DRUPAL_ROOT);
+ if (substr($error['%file'], 0, $root_length) == DRUPAL_ROOT) {
+ $error['%file'] = substr($error['%file'], $root_length + 1);
+ }
+ // Should not translate the string to avoid errors producing more errors.
+ $message = String::format('%type: !message in %function (line %line of %file).', $error);
+
+ // Check if verbose error reporting is on.
+ $error_level = $this->container->get('config.factory')->get('system.logging')->get('error_level');
+
+ if ($error_level == ERROR_REPORTING_DISPLAY_VERBOSE) {
+ $backtrace_exception = $exception;
+ while ($backtrace_exception->getPrevious()) {
+ $backtrace_exception = $backtrace_exception->getPrevious();
+ }
+ $backtrace = $backtrace_exception->getTrace();
+ // First trace is the error itself, already contained in the message.
+ // While the second trace is the error source and also contained in the
+ // message, the message doesn't contain argument values, so we output it
+ // once more in the backtrace.
+ array_shift($backtrace);
+ // Generate a backtrace containing only scalar argument values.
+ $message .= '<pre class="backtrace">' . Error::formatFlattenedBacktrace($backtrace) . '</pre>';
+ }
+ drupal_set_message($message, $class, TRUE);
}
$page_content = array(
diff --git a/core/lib/Drupal/Core/Utility/Error.php b/core/lib/Drupal/Core/Utility/Error.php
index 669cca0..e3b084f 100644
--- a/core/lib/Drupal/Core/Utility/Error.php
+++ b/core/lib/Drupal/Core/Utility/Error.php
@@ -185,4 +185,56 @@ class Error {
return $return;
}
+ /**
+ * Formats a flattened backtrace into a plain-text string.
+ *
+ * The calls show values for scalar arguments and type names for complex ones.
+ *
+ * @param array $backtrace
+ * The backtrace of a Symfony\Component\Debug\Exception\FlattenException.
+ *
+ * @return string
+ * A plain-text line-wrapped string ready to be put inside <pre>.
+ */
+ public static function formatFlattenedBacktrace(array $backtrace) {
+ $return = '';
+
+ foreach ($backtrace as $trace) {
+ $call = array('function' => '', 'args' => array());
+
+ if (isset($trace['class'])) {
+ $call['function'] = $trace['class'] . $trace['type'] . $trace['function'];
+ }
+ elseif (isset($trace['function'])) {
+ $call['function'] = $trace['function'];
+ }
+ else {
+ $call['function'] = 'main';
+ }
+
+ if (isset($trace['args'])) {
+ foreach ($trace['args'] as $arg) {
+ $type = $arg[0];
+ $value = $arg[1];
+ if ($type == 'array') {
+ $call['args'][] = '[' . ucfirst($type) . ']';
+ }
+ elseif ($type == 'null') {
+ $call['args'][] = strtoupper($type);
+ }
+ elseif ($type == 'boolean') {
+ $call['args'][] = $value ? 'TRUE' : 'FALSE';
+ }
+ else {
+ $call['args'][] = $value;
+ }
+ }
+ }
+
+ $return .= $call['function'] . '(' . implode(', ', $call['args']) . ")\n";
+ }
+
+ return $return;
+ }
+
}