diff --git a/includes/errors.inc b/includes/errors.inc index 3a97b6d..5f1584c 100644 --- a/includes/errors.inc +++ b/includes/errors.inc @@ -67,7 +67,8 @@ function _drupal_error_handler_real($error_level, $message, $filename, $line, $c if ($error_level & error_reporting()) { $types = drupal_error_levels(); list($severity_msg, $severity_level) = $types[$error_level]; - $caller = _drupal_get_last_caller(debug_backtrace()); + $backtrace = debug_backtrace(); + $caller = _drupal_get_last_caller($backtrace); if (!function_exists('filter_xss_admin')) { require_once DRUPAL_ROOT . '/includes/common.inc'; @@ -83,6 +84,7 @@ function _drupal_error_handler_real($error_level, $message, $filename, $line, $c '%file' => $caller['file'], '%line' => $caller['line'], 'severity_level' => $severity_level, + 'backtrace' => $backtrace, ), $error_level == E_RECOVERABLE_ERROR); } } @@ -189,6 +191,10 @@ function _drupal_log_error($error, $fatal = FALSE) { drupal_maintenance_theme(); } + // Backtrace array is not a valid replacement value for t(). + $backtrace = $error['backtrace']; + unset($error['backtrace']); + // When running inside the testing framework, we relay the errors // to the tested site by the way of HTTP headers. $test_info = &$GLOBALS['drupal_test_info']; @@ -237,13 +243,50 @@ function _drupal_log_error($error, $fatal = FALSE) { $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); + // Do not expose DRUPAL_ROOT, if possible. + $root_length = strlen(DRUPAL_ROOT); + if (substr($error['%file'], 0, $root_length) == DRUPAL_ROOT) { + $error['%file'] = substr($error['%file'], $root_length + 1); + } + $message = t('%type: !message in %function (line %line of %file).', $error); + + // 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 .= '
';
+      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';
+        }
+        foreach ($trace['args'] as $arg) {
+          if (is_scalar($arg)) {
+            $call['args'][] = is_string($arg) ? "'$arg'" : $arg;
+          }
+          else {
+            $call['args'][] = ucfirst(gettype($arg));
+          }
+        }
+        $message .= $call['function'] . '(' . implode(', ', $call['args']) . ")\n";
+      }
+      $message .= '
'; + drupal_set_message($message, $class); } if ($fatal) { @@ -260,11 +303,11 @@ function _drupal_log_error($error, $fatal = FALSE) { * Gets the last caller from a backtrace. * * @param $backtrace - * A standard PHP backtrace. + * A standard PHP backtrace. Passed by reference. * @return * An associative array with keys 'file', 'line' and 'function'. */ -function _drupal_get_last_caller($backtrace) { +function _drupal_get_last_caller(&$backtrace) { // Errors that occur inside PHP internal functions do not generate // information about file and line. Ignore black listed functions. $blacklist = array('debug', '_drupal_error_handler', '_drupal_exception_handler'); diff --git a/modules/field/modules/text/text.module b/modules/field/modules/text/text.module index 89c605c..d92c104 100644 --- a/modules/field/modules/text/text.module +++ b/modules/field/modules/text/text.module @@ -9,6 +9,7 @@ * Implements hook_help(). */ function text_help($path, $arg) { + $foo = $bar; switch ($path) { case 'admin/help#text': $output = '';