function backtrace_error_handler

Same name in other branches
  1. 7.x-1.x devel.module \backtrace_error_handler()
  2. 8.x-1.x devel.module \backtrace_error_handler()
  3. 4.x devel.module \backtrace_error_handler()
  4. 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'
devel_set_handler in ./devel.module

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);
    }
}