00001 <?php
00002
00003
00011
00012
00013
00014
00015
00016 set_error_handler('_drupal_error_handler');
00017 set_exception_handler('_drupal_exception_handler');
00018
00033 function _drupal_error_handler($error_level, $message, $filename, $line, $context) {
00034 if ($error_level & error_reporting()) {
00035
00036 $types = array(
00037 E_ERROR => 'Error',
00038 E_WARNING => 'Warning',
00039 E_PARSE => 'Parse error',
00040 E_NOTICE => 'Notice',
00041 E_CORE_ERROR => 'Core error',
00042 E_CORE_WARNING => 'Core warning',
00043 E_COMPILE_ERROR => 'Compile error',
00044 E_COMPILE_WARNING => 'Compile warning',
00045 E_USER_ERROR => 'User error',
00046 E_USER_WARNING => 'User warning',
00047 E_USER_NOTICE => 'User notice',
00048 E_STRICT => 'Strict warning',
00049 E_RECOVERABLE_ERROR => 'Recoverable fatal error'
00050 );
00051 $backtrace = debug_backtrace();
00052
00053 $caller = _drupal_get_last_caller(debug_backtrace());
00054
00055
00056 _drupal_log_error(array(
00057 '%type' => isset($types[$error_level]) ? $types[$error_level] : 'Unknown error',
00058 '%message' => $message,
00059 '%function' => $caller['function'],
00060 '%file' => $caller['file'],
00061 '%line' => $caller['line'],
00062 ), $error_level == E_RECOVERABLE_ERROR);
00063 }
00064 }
00065
00076 function _drupal_exception_handler($exception) {
00077
00078 _drupal_log_error(_drupal_decode_exception($exception), TRUE);
00079 }
00080
00088 function _drupal_decode_exception($exception) {
00089 $backtrace = $exception->getTrace();
00090
00091 array_unshift($backtrace, array('line' => $exception->getLine(), 'file' => $exception->getFile()));
00092
00093
00094
00095 if ($exception instanceof PDOException) {
00096
00097
00098
00099
00100 $db_functions = array('db_query', '_db_query', 'pager_query', 'db_query_range', 'db_query_temporary', 'update_sql');
00101 while (!empty($backtrace[1]) && ($caller = $backtrace[1]) &&
00102 ((isset($caller['class']) && (strpos($caller['class'], 'Query') !== FALSE || strpos($caller['class'], 'Database') !== FALSE)) ||
00103 in_array($caller['function'], $db_functions))) {
00104
00105 array_shift($backtrace);
00106 }
00107 }
00108 $caller = _drupal_get_last_caller($backtrace);
00109
00110 return array(
00111 '%type' => get_class($exception),
00112 '%message' => $exception->getMessage(),
00113 '%function' => $caller['function'],
00114 '%file' => $caller['file'],
00115 '%line' => $caller['line'],
00116 );
00117 }
00118
00127 function _drupal_log_error($error, $fatal = FALSE) {
00128
00129
00130 if ($fatal && (drupal_get_bootstrap_phase() != DRUPAL_BOOTSTRAP_FULL)) {
00131 unset($GLOBALS['theme']);
00132 if (!defined('MAINTENANCE_MODE')) {
00133 define('MAINTENANCE_MODE', 'error');
00134 }
00135 drupal_maintenance_theme();
00136 }
00137
00138
00139
00140 if (preg_match("/^simpletest\d+/", $_SERVER['HTTP_USER_AGENT']) && !headers_sent() && (!defined('SIMPLETEST_COLLECT_ERRORS') || SIMPLETEST_COLLECT_ERRORS)) {
00141 static $number = 0;
00142 $assertion = array(
00143 $error['%message'],
00144 $error['%type'],
00145 array(
00146 'function' => $error['%function'],
00147 'file' => $error['%file'],
00148 'line' => $error['%line'],
00149 ),
00150 );
00151 header('X-Drupal-Assertion-' . $number . ': ' . rawurlencode(serialize($assertion)));
00152 $number++;
00153 }
00154
00155
00156
00157 $error_level = variable_get('error_level', 2);
00158 if ($error_level == 2 || ($error_level == 1 && $error['%type'] != 'Notice') || (defined('MAINTENANCE_MODE') && MAINTENANCE_MODE == 'update')) {
00159 drupal_set_message(t('%type: %message in %function (line %line of %file).', $error), 'error');
00160 }
00161
00162 try {
00163 watchdog('php', '%type: %message in %function (line %line of %file).', $error, WATCHDOG_ERROR);
00164 }
00165 catch (Exception $e) {
00166 $new_error = _drupal_decode_exception($e);
00167 drupal_set_message(t('%type: %message in %function (line %line of %file).', $new_error), 'error');
00168 }
00169
00170 if ($fatal) {
00171 drupal_set_header('503 Service unavailable');
00172 drupal_set_title(t('Error'));
00173 if (!defined('MAINTENANCE_MODE') && drupal_get_bootstrap_phase() == DRUPAL_BOOTSTRAP_FULL) {
00174
00175 $page = drupal_get_page(t('The website encountered an unexpected error. Please try again later.'));
00176 $page['#show_blocks'] = FALSE;
00177 print drupal_render_page($page);
00178 }
00179 else {
00180 print theme('maintenance_page', t('The website encountered an unexpected error. Please try again later.'), FALSE);
00181 }
00182 exit;
00183 }
00184 }
00185
00194 function _drupal_get_last_caller($backtrace) {
00195
00196
00197 while ($backtrace && !isset($backtrace[0]['line'])) {
00198 array_shift($backtrace);
00199 }
00200
00201
00202
00203 $call = $backtrace[0];
00204
00205
00206 if (isset($backtrace[1])) {
00207 if (isset($backtrace[1]['class'])) {
00208 $call['function'] = $backtrace[1]['class'] . $backtrace[1]['type'] . $backtrace[1]['function'] . '()';
00209 }
00210 else {
00211 $call['function'] = $backtrace[1]['function'] . '()';
00212 }
00213 }
00214 else {
00215 $call['function'] = 'main()';
00216 }
00217 return $call;
00218 }