Issue #2536052 by znerol, jungle, Rishi Kulshreshtha, smustgrave, alexpott, dawehner, quietone: Remove try...catch from SessionHandler::write
parent
2231e59295
commit
ba5d33817a
|
@ -5,7 +5,6 @@ namespace Drupal\Core\Session;
|
|||
use Drupal\Component\Utility\Crypt;
|
||||
use Drupal\Core\Database\Connection;
|
||||
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
|
||||
use Drupal\Core\Utility\Error;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy;
|
||||
|
||||
|
@ -71,32 +70,18 @@ class SessionHandler extends AbstractProxy implements \SessionHandlerInterface {
|
|||
*/
|
||||
#[\ReturnTypeWillChange]
|
||||
public function write(#[\SensitiveParameter] $sid, $value) {
|
||||
// The exception handler is not active at this point, so we need to do it
|
||||
// manually.
|
||||
try {
|
||||
$request = $this->requestStack->getCurrentRequest();
|
||||
$fields = [
|
||||
'uid' => $request->getSession()->get('uid', 0),
|
||||
'hostname' => $request->getClientIP(),
|
||||
'session' => $value,
|
||||
'timestamp' => REQUEST_TIME,
|
||||
];
|
||||
$this->connection->merge('sessions')
|
||||
->keys(['sid' => Crypt::hashBase64($sid)])
|
||||
->fields($fields)
|
||||
->execute();
|
||||
return TRUE;
|
||||
}
|
||||
catch (\Exception $exception) {
|
||||
require_once DRUPAL_ROOT . '/core/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>' . Error::renderExceptionSafe($exception) . '</p><hr />';
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
$request = $this->requestStack->getCurrentRequest();
|
||||
$fields = [
|
||||
'uid' => $request->getSession()->get('uid', 0),
|
||||
'hostname' => $request->getClientIP(),
|
||||
'session' => $value,
|
||||
'timestamp' => REQUEST_TIME,
|
||||
];
|
||||
$this->connection->merge('sessions')
|
||||
->keys(['sid' => Crypt::hashBase64($sid)])
|
||||
->fields($fields)
|
||||
->execute();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -161,3 +161,13 @@ session_test.has_bag_flag:
|
|||
no_cache: TRUE
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
session_test.trigger_write_exception:
|
||||
path: '/session-test/trigger-write-exception'
|
||||
defaults:
|
||||
_title: 'Trigger an exception when the session is written'
|
||||
_controller: '\Drupal\session_test\Controller\SessionTestController::triggerWriteException'
|
||||
options:
|
||||
no_cache: TRUE
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
|
|
@ -245,4 +245,43 @@ class SessionTestController extends ControllerBase {
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Trigger an exception when the session is written.
|
||||
*
|
||||
* @param \Symfony\Component\HttpFoundation\Request $request
|
||||
* The request object.
|
||||
*/
|
||||
public function triggerWriteException(Request $request) {
|
||||
$session = $request->getSession();
|
||||
$session->set('test_value', 'Ensure session contains some data');
|
||||
|
||||
// Move sessions table out of the way.
|
||||
$schema = \Drupal::database()->schema();
|
||||
$schema->renameTable('sessions', 'sessions_tmp');
|
||||
|
||||
// There needs to be a session table, otherwise
|
||||
// InstallerRedirectTrait::shouldRedirectToInstaller() will instruct the
|
||||
// handleException::handleException to redirect to the installer.
|
||||
$schema->createTable('sessions', [
|
||||
'description' => "Fake sessions table missing some columns.",
|
||||
'fields' => [
|
||||
'sid' => [
|
||||
'description' => "A fake session ID column.",
|
||||
'type' => 'varchar_ascii',
|
||||
'length' => 128,
|
||||
'not null' => TRUE,
|
||||
],
|
||||
],
|
||||
'primary key' => ['sid'],
|
||||
]);
|
||||
|
||||
drupal_register_shutdown_function(function () {
|
||||
$schema = \Drupal::database()->schema();
|
||||
$schema->dropTable('sessions');
|
||||
$schema->renameTable('sessions_tmp', 'sessions');
|
||||
});
|
||||
|
||||
return new Response();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -358,6 +358,20 @@ class SessionTest extends BrowserTestBase {
|
|||
$this->assertSession()->statusCodeEquals(200);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test exception thrown during session write close.
|
||||
*/
|
||||
public function testSessionWriteError() {
|
||||
// Login to ensure a session exists.
|
||||
$user = $this->drupalCreateUser([]);
|
||||
$this->drupalLogin($user);
|
||||
|
||||
// Trigger an exception in SessionHandler::write().
|
||||
$this->expectExceptionMessageMatches("/^Drupal\\\\Core\\\\Database\\\\DatabaseExceptionWrapper:/");
|
||||
$this->drupalGet('/session-test/trigger-write-exception');
|
||||
$this->assertSession()->statusCodeEquals(500);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the cookie file so that it refers to the specified user.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue