function backtrace_error_handler
Same name in other branches
- 7.x-1.x devel.module \backtrace_error_handler()
- 8.x-1.x devel.module \backtrace_error_handler()
- 4.x devel.module \backtrace_error_handler()
- 5.x devel.module \backtrace_error_handler()
Display backtrace showing the route of calls to the current error.
Parameters
$error_level: The level of the error raised.
$message: The error message.
$filename: The filename that the error was raised in.
$line: The line number the error was raised at.
$context: An array that points to the active symbol table at the point the error occurred.
1 string reference to 'backtrace_error_handler'
File
-
./
devel.module, line 484
Code
function backtrace_error_handler($error_level, $message, $filename, $line, $context) {
// Don't respond to the error if it was suppressed with a '@'.
if (error_reporting() == 0) {
return;
}
// Don't respond to warning caused by ourselves.
if (preg_match('#Cannot modify header information - headers already sent by \\([^\\)]*[/\\\\]devel[/\\\\]#', $message)) {
return;
}
// We can't use the PHP E_* constants here as not all versions of PHP have all
// the constants defined, so for consistency, we just use the numeric equivalent.
$types = array(
1 => array(
'Error',
WATCHDOG_ERROR,
),
2 => array(
'Warning',
WATCHDOG_WARNING,
),
4 => array(
'Parse error',
WATCHDOG_ERROR,
),
8 => array(
'Notice',
WATCHDOG_NOTICE,
),
16 => array(
'Core error',
WATCHDOG_ERROR,
),
32 => array(
'Core warning',
WATCHDOG_WARNING,
),
64 => array(
'Compile error',
WATCHDOG_ERROR,
),
128 => array(
'Compile warning',
WATCHDOG_WARNING,
),
256 => array(
'User error',
WATCHDOG_ERROR,
),
512 => array(
'User warning',
WATCHDOG_WARNING,
),
1024 => array(
'User notice',
WATCHDOG_NOTICE,
),
2048 => array(
'Strict warning',
WATCHDOG_DEBUG,
),
4096 => array(
'Recoverable fatal error',
WATCHDOG_ERROR,
),
8192 => array(
'Deprecated',
WATCHDOG_WARNING,
),
16384 => array(
'User deprecated',
WATCHDOG_WARNING,
),
);
$type = isset($types[$error_level]) ? $types[$error_level] : array(
'Unknown error',
WATCHDOG_ERROR,
);
// Hide stack trace and parameters from unqualified users.
if (!user_access('access devel information')) {
// Do what core does in common.inc.
// (We need to duplicate the core code here rather than calling it
// to avoid having the backtrace_error_handler() on top of the call stack.)
if (function_exists('_drupal_get_last_caller') && function_exists('_drupal_log_error')) {
// Use the functions in the D6-core-simpletest.patch.
if ($error_level) {
$caller = _drupal_get_last_caller(debug_backtrace());
// We treat recoverable errors as fatal.
_drupal_log_error(array(
'%type' => $type[1],
'%message' => $message,
'%function' => $caller['function'],
'%file' => $caller['file'],
'%line' => $caller['line'],
), $error_level == E_RECOVERABLE_ERROR);
}
}
else {
// Duplicate the drupal_error_handler() code.
$errno = $error_level;
// If the @ error suppression operator was used, error_reporting will have
// been temporarily set to 0.
if (error_reporting() == 0) {
return;
}
if ($errno & (E_ALL ^ E_DEPRECATED)) {
$types = array(
1 => 'error',
2 => 'warning',
4 => 'parse error',
8 => 'notice',
16 => 'core error',
32 => 'core warning',
64 => 'compile error',
128 => 'compile warning',
256 => 'user error',
512 => 'user warning',
1024 => 'user notice',
2048 => 'strict warning',
4096 => 'recoverable fatal error',
);
// For database errors, we want the line number/file name of the place that
// the query was originally called, not _db_query().
if (isset($context[DB_ERROR])) {
$backtrace = array_reverse(debug_backtrace());
// List of functions where SQL queries can originate.
$query_functions = array(
'db_query',
'pager_query',
'db_query_range',
'db_query_temporary',
'update_sql',
);
// Determine where query function was called, and adjust line/file
// accordingly.
foreach ($backtrace as $index => $function) {
if (in_array($function['function'], $query_functions)) {
$line = $backtrace[$index]['line'];
$filename = $backtrace[$index]['file'];
break;
}
}
}
// Try to use filter_xss(). If it's too early in the bootstrap process for
// filter_xss() to be loaded, use check_plain() instead.
$entry = check_plain($types[$errno]) . ': ' . (function_exists('filter_xss') ? filter_xss($message) : check_plain($message)) . ' in ' . check_plain($filename) . ' on line ' . check_plain($line) . '.';
// Force display of error messages in update.php.
if (variable_get('error_level', 1) == 1 || strstr($_SERVER['SCRIPT_NAME'], 'update.php')) {
drupal_set_message($entry, 'error');
}
watchdog('php', '%message in %file on line %line.', array(
'%error' => $types[$errno],
'%message' => $message,
'%file' => $filename,
'%line' => $line,
), WATCHDOG_ERROR);
}
}
return;
}
if ($error_level & (E_ALL ^ E_DEPRECATED)) {
// Only write each distinct NOTICE message once, as repeats do not give any
// further information and can choke the page output.
if ($error_level == E_NOTICE) {
static $written = array();
if (!empty($written[$line][$filename][$message])) {
return;
}
$written[$line][$filename][$message] = TRUE;
}
$backtrace = debug_backtrace();
$variables = array(
'%error' => $type[0],
'%message' => $message,
'%function' => $backtrace[1]['function'] . '()',
'%file' => $filename,
'%line' => $line,
);
if (variable_get('error_level', 1) == 1) {
print t('%error: %message in %function (line %line of %file).', $variables) . " =>\n";
ddebug_backtrace(1);
// Also show the standard drupal message if this was requested via the admin option
// for both backtrace and message.
if (variable_get('devel_error_handler', DEVEL_ERROR_HANDLER_STANDARD) == DEVEL_ERROR_HANDLER_BACKTRACE_AND_MESSAGE) {
drupal_set_message(t('%error: %message in %function (line %line of %file).', $variables), $type[1] <= WATCHDOG_ERROR ? 'error' : 'warning');
}
}
watchdog('php', '%error: %message in %function (line %line of %file).', $variables, WATCHDOG_ERROR);
}
}