Loading core/lib/Drupal/Core/Session/SessionHandler.php +12 −27 Original line number Diff line number Diff line Loading @@ -5,7 +5,6 @@ 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; Loading Loading @@ -71,9 +70,6 @@ public function read(#[\SensitiveParameter] $sid) { */ #[\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), Loading @@ -87,17 +83,6 @@ public function write(#[\SensitiveParameter] $sid, $value) { ->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; } } /** * {@inheritdoc} Loading core/modules/system/tests/modules/session_test/session_test.routing.yml +10 −0 Original line number Diff line number Diff line Loading @@ -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' core/modules/system/tests/modules/session_test/src/Controller/SessionTestController.php +39 −0 Original line number Diff line number Diff line Loading @@ -245,4 +245,43 @@ public function hasSessionBagFlag(Request $request) { ); } /** * 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(); } } core/modules/system/tests/src/Functional/Session/SessionTest.php +14 −0 Original line number Diff line number Diff line Loading @@ -358,6 +358,20 @@ public function testSessionBag() { $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 Loading
core/lib/Drupal/Core/Session/SessionHandler.php +12 −27 Original line number Diff line number Diff line Loading @@ -5,7 +5,6 @@ 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; Loading Loading @@ -71,9 +70,6 @@ public function read(#[\SensitiveParameter] $sid) { */ #[\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), Loading @@ -87,17 +83,6 @@ public function write(#[\SensitiveParameter] $sid, $value) { ->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; } } /** * {@inheritdoc} Loading
core/modules/system/tests/modules/session_test/session_test.routing.yml +10 −0 Original line number Diff line number Diff line Loading @@ -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'
core/modules/system/tests/modules/session_test/src/Controller/SessionTestController.php +39 −0 Original line number Diff line number Diff line Loading @@ -245,4 +245,43 @@ public function hasSessionBagFlag(Request $request) { ); } /** * 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(); } }
core/modules/system/tests/src/Functional/Session/SessionTest.php +14 −0 Original line number Diff line number Diff line Loading @@ -358,6 +358,20 @@ public function testSessionBag() { $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