Commit 8fb6adbc authored by Dries's avatar Dries
Browse files

- Patch #742246 by jbrown, noahb, aspilicious, alexanderpas, rfay:handle uncaught exceptions.

parent 15bca6e4
......@@ -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 />';
}
}
}
......@@ -138,6 +138,29 @@ function _drupal_render_exception_safe($exception) {
return strtr('%type: %message in %function (line %line of %file).', _drupal_decode_exception($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.
*
......@@ -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
......
......@@ -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;
}
}
/**
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment