diff options
author | Dries Buytaert <dries@buytaert.net> | 2010-06-05 13:30:42 +0000 |
---|---|---|
committer | Dries Buytaert <dries@buytaert.net> | 2010-06-05 13:30:42 +0000 |
commit | 8fb6adbc21302e896b1019aad2edd5c87a518a98 (patch) | |
tree | 986bf9d2f093dbe6631cedf7d855701c44b50d69 | |
parent | 15bca6e4623e0344c4165b5e9ac6f4502e6f2481 (diff) | |
download | brdo-8fb6adbc21302e896b1019aad2edd5c87a518a98.tar.gz brdo-8fb6adbc21302e896b1019aad2edd5c87a518a98.tar.bz2 |
- Patch #742246 by jbrown, noahb, aspilicious, alexanderpas, rfay:handle uncaught exceptions.
-rw-r--r-- | includes/bootstrap.inc | 18 | ||||
-rw-r--r-- | includes/errors.inc | 27 | ||||
-rw-r--r-- | includes/session.inc | 84 |
3 files changed, 80 insertions, 49 deletions
diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc index 45835e830..0bcd8dc1a 100644 --- a/includes/bootstrap.inc +++ b/includes/bootstrap.inc @@ -2051,11 +2051,10 @@ function _drupal_exception_handler($exception) { catch (Exception $exception2) { // Another uncaught exception was thrown while handling the first one. // If we are displaying errors, then do so with no possibility of a further uncaught exception being thrown. - $error_level = variable_get('error_level', ERROR_REPORTING_DISPLAY_ALL); - if ($error_level == ERROR_REPORTING_DISPLAY_ALL || (defined('MAINTENANCE_MODE') && MAINTENANCE_MODE == 'update')) { - print 'Additional uncaught exception thrown while handling exception.<br /><br />'; - print '<b>Original</b><br />' . _drupal_render_exception_safe($exception) . '<br /><br />'; - print '<b>Additional</b><br />' . _drupal_render_exception_safe($exception2) . '<br /><br />'; + if (error_displayable()) { + print '<h1>Additional uncaught exception thrown while handling exception.</h1>'; + print '<h2>Original</h2><p>' . _drupal_render_exception_safe($exception) . '</p>'; + print '<h2>Additional</h2><p>' . _drupal_render_exception_safe($exception2) . '</p><hr />'; } } } @@ -2963,11 +2962,10 @@ function _drupal_shutdown_function() { } catch (Exception $exception) { // If we are displaying errors, then do so with no possibility of a further uncaught exception being thrown. - $error_level = variable_get('error_level', ERROR_REPORTING_DISPLAY_ALL); - if ($error_level == ERROR_REPORTING_DISPLAY_ALL || (defined('MAINTENANCE_MODE') && MAINTENANCE_MODE == 'update')) { - require_once DRUPAL_ROOT . '/includes/errors.inc'; - print 'Uncaught exception thrown in shutdown function.<br /><br />'; - print _drupal_render_exception_safe($exception) . '<br /><br />'; + require_once DRUPAL_ROOT . '/includes/errors.inc'; + if (error_displayable()) { + print '<h1>Uncaught exception thrown in shutdown function.</h1>'; + print '<p>' . _drupal_render_exception_safe($exception) . '</p><hr />'; } } } diff --git a/includes/errors.inc b/includes/errors.inc index 7b5a44241..1047a6665 100644 --- a/includes/errors.inc +++ b/includes/errors.inc @@ -139,6 +139,29 @@ function _drupal_render_exception_safe($exception) { } /** + * Determines whether an error should be displayed. + * + * When in maintenance mode or when error_level is ERROR_REPORTING_DISPLAY_ALL, + * all errors should be displayed. For ERROR_REPORTING_DISPLAY_SOME, $error + * will be examined to determine if it should be displayed. + * + * @param $error + * Optional error to examine for ERROR_REPORTING_DISPLAY_SOME. + * + * @return + * TRUE if an error should be displayed. + */ +function error_displayable($error = NULL) { + $error_level = variable_get('error_level', ERROR_REPORTING_DISPLAY_ALL); + $updating = (defined('MAINTENANCE_MODE') && MAINTENANCE_MODE == 'update'); + $all_errors_displayed = ($error_level == ERROR_REPORTING_DISPLAY_ALL); + $error_needs_display = ($error_level == ERROR_REPORTING_DISPLAY_SOME && + isset($error) && $error['%type'] != 'Notice' && $error['%type'] != 'Strict warning'); + + return ($updating || $all_errors_displayed || $error_needs_display); +} + +/** * Log a PHP error or exception, display an error page in fatal cases. * * @param $error @@ -200,9 +223,7 @@ function _drupal_log_error($error, $fatal = FALSE) { else { // Display the message if the current error reporting level allows this type // of message to be displayed, and unconditionnaly in update.php. - $error_level = variable_get('error_level', ERROR_REPORTING_DISPLAY_ALL); - $display_error = $error_level == ERROR_REPORTING_DISPLAY_ALL || ($error_level == ERROR_REPORTING_DISPLAY_SOME && $error['%type'] != 'Notice' && $error['%type'] != 'Strict warning'); - if ($display_error || (defined('MAINTENANCE_MODE') && MAINTENANCE_MODE == 'update')) { + if (error_displayable($error)) { $class = 'error'; // If error type is 'User notice' then treat it as debug information diff --git a/includes/session.inc b/includes/session.inc index 67c52e6ef..ce5524a22 100644 --- a/includes/session.inc +++ b/includes/session.inc @@ -140,46 +140,58 @@ function _drupal_session_read($sid) { function _drupal_session_write($sid, $value) { global $user, $is_https; - if (!drupal_save_session()) { - // We don't have anything to do if we are not allowed to save the session. - return; - } - - $fields = array( - 'uid' => $user->uid, - 'cache' => isset($user->cache) ? $user->cache : 0, - 'hostname' => ip_address(), - 'session' => $value, - 'timestamp' => REQUEST_TIME, - ); - $key = array('sid' => $sid); - if ($is_https) { - $key['ssid'] = $sid; - $insecure_session_name = substr(session_name(), 1); - // The "secure pages" setting allows a site to simultaneously use both - // secure and insecure session cookies. If enabled, use the insecure session - // identifier as the sid. - if (variable_get('https', FALSE) && isset($_COOKIE[$insecure_session_name])) { - $key['sid'] = $_COOKIE[$insecure_session_name]; + // The exception handler is not active at this point, so we need to do it manually. + try { + if (!drupal_save_session()) { + // We don't have anything to do if we are not allowed to save the session. + return; } - } - db_merge('sessions') - ->key($key) - ->fields($fields) - ->execute(); - // Last access time is updated no more frequently than once every 180 seconds. - // This reduces contention in the users table. - if ($user->uid && REQUEST_TIME - $user->access > variable_get('session_write_interval', 180)) { - db_update('users') - ->fields(array( - 'access' => REQUEST_TIME - )) - ->condition('uid', $user->uid) + $fields = array( + 'uid' => $user->uid, + 'cache' => isset($user->cache) ? $user->cache : 0, + 'hostname' => ip_address(), + 'session' => $value, + 'timestamp' => REQUEST_TIME, + ); + $key = array('sid' => $sid); + if ($is_https) { + $key['ssid'] = $sid; + $insecure_session_name = substr(session_name(), 1); + // The "secure pages" setting allows a site to simultaneously use both + // secure and insecure session cookies. If enabled, use the insecure session + // identifier as the sid. + if (variable_get('https', FALSE) && isset($_COOKIE[$insecure_session_name])) { + $key['sid'] = $_COOKIE[$insecure_session_name]; + } + } + db_merge('sessions') + ->key($key) + ->fields($fields) ->execute(); - } - return TRUE; + // Last access time is updated no more frequently than once every 180 seconds. + // This reduces contention in the users table. + if ($user->uid && REQUEST_TIME - $user->access > variable_get('session_write_interval', 180)) { + db_update('users') + ->fields(array( + 'access' => REQUEST_TIME + )) + ->condition('uid', $user->uid) + ->execute(); + } + + return TRUE; + } + catch (Exception $exception) { + require_once DRUPAL_ROOT . '/includes/errors.inc'; + // If we are displaying errors, then do so with no possibility of a further uncaught exception being thrown. + if (error_displayable()) { + print '<h1>Uncaught exception thrown in session handler.</h1>'; + print '<p>' . _drupal_render_exception_safe($exception) . '</p><hr />'; + } + return FALSE; + } } /** |