diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index 764527ee1b5..b2924892b02 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -2585,12 +2585,16 @@ 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.
- require_once __DIR__ . '/errors.inc';
- if (error_displayable()) {
- print '
Uncaught exception thrown in shutdown function.
';
- print '' . Error::renderExceptionSafe($exception) . '
';
+ // If using PHP-FPM then fastcgi_finish_request() will have been fired
+ // preventing further output to the browser.
+ if (!function_exists('fastcgi_finish_request')) {
+ // If we are displaying errors, then do so with no possibility of a
+ // further uncaught exception being thrown.
+ require_once __DIR__ . '/errors.inc';
+ if (error_displayable()) {
+ print 'Uncaught exception thrown in shutdown function.
';
+ print '' . Error::renderExceptionSafe($exception) . '
';
+ }
}
error_log($exception);
}
diff --git a/core/modules/system/lib/Drupal/system/Tests/System/ShutdownFunctionsTest.php b/core/modules/system/lib/Drupal/system/Tests/System/ShutdownFunctionsTest.php
index 96b2f8d5741..2c42bd00dbc 100644
--- a/core/modules/system/lib/Drupal/system/Tests/System/ShutdownFunctionsTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/System/ShutdownFunctionsTest.php
@@ -36,11 +36,23 @@ class ShutdownFunctionsTest extends WebTestBase {
$arg1 = $this->randomName();
$arg2 = $this->randomName();
$this->drupalGet('system-test/shutdown-functions/' . $arg1 . '/' . $arg2);
- $this->assertText(t('First shutdown function, arg1 : @arg1, arg2: @arg2', array('@arg1' => $arg1, '@arg2' => $arg2)));
- $this->assertText(t('Second shutdown function, arg1 : @arg1, arg2: @arg2', array('@arg1' => $arg1, '@arg2' => $arg2)));
- // Make sure exceptions displayed through
- // \Drupal\Core\Utility\Error::renderExceptionSafe() are correctly escaped.
- $this->assertRaw('Drupal is <blink>awesome</blink>.');
+ // If using PHP-FPM then fastcgi_finish_request() will have been fired
+ // returning the response before shutdown functions have fired.
+ // @see \Drupal\system_test\Controller\SystemTestController::shutdownFunctions()
+ $server_using_fastcgi = strpos($this->drupalGetContent(), 'The function fastcgi_finish_request exists when serving the request.');
+ if ($server_using_fastcgi) {
+ // We need to wait to ensure that the shutdown functions have fired.
+ sleep(1);
+ }
+ $this->assertEqual(\Drupal::state()->get('_system_test_first_shutdown_function'), array($arg1, $arg2));
+ $this->assertEqual(\Drupal::state()->get('_system_test_second_shutdown_function'), array($arg1, $arg2));
+
+ if (!$server_using_fastcgi) {
+ // Make sure exceptions displayed through
+ // \Drupal\Core\Utility\Error::renderExceptionSafe() are correctly
+ // escaped.
+ $this->assertRaw('Drupal is <blink>awesome</blink>.');
+ }
}
}
diff --git a/core/modules/system/tests/modules/system_test/lib/Drupal/system_test/Controller/SystemTestController.php b/core/modules/system/tests/modules/system_test/lib/Drupal/system_test/Controller/SystemTestController.php
index 5d7f49ca667..868117aebc2 100644
--- a/core/modules/system/tests/modules/system_test/lib/Drupal/system_test/Controller/SystemTestController.php
+++ b/core/modules/system/tests/modules/system_test/lib/Drupal/system_test/Controller/SystemTestController.php
@@ -68,6 +68,14 @@ class SystemTestController extends ControllerBase {
*/
public function shutdownFunctions($arg1, $arg2) {
system_test_page_shutdown_functions($arg1, $arg2);
+ // If using PHP-FPM then fastcgi_finish_request() will have been fired
+ // preventing further output to the browser which means that the escaping of
+ // the exception message can not be tested.
+ // @see _drupal_shutdown_function()
+ // @see \Drupal\system\Tests\System\ShutdownFunctionsTest
+ if (function_exists('fastcgi_finish_request')) {
+ return 'The function fastcgi_finish_request exists when serving the request.';
+ }
}
}
diff --git a/core/modules/system/tests/modules/system_test/system_test.module b/core/modules/system/tests/modules/system_test/system_test.module
index 040d9f31573..1eda491bca9 100644
--- a/core/modules/system/tests/modules/system_test/system_test.module
+++ b/core/modules/system/tests/modules/system_test/system_test.module
@@ -140,9 +140,8 @@ function system_test_page_shutdown_functions($arg1, $arg2) {
* Dummy shutdown function which registers another shutdown function.
*/
function _system_test_first_shutdown_function($arg1, $arg2) {
- // Output something, page has already been printed and the session stored
- // so we can't use drupal_set_message.
- print t('First shutdown function, arg1 : @arg1, arg2: @arg2', array('@arg1' => $arg1, '@arg2' => $arg2));
+ // Set something to ensure that this function got called.
+ \Drupal::state()->set('_system_test_first_shutdown_function', array($arg1, $arg2));
drupal_register_shutdown_function('_system_test_second_shutdown_function', $arg1, $arg2);
}
@@ -150,14 +149,13 @@ function _system_test_first_shutdown_function($arg1, $arg2) {
* Dummy shutdown function.
*/
function _system_test_second_shutdown_function($arg1, $arg2) {
- // Output something, page has already been printed and the session stored
- // so we can't use drupal_set_message.
- print t('Second shutdown function, arg1 : @arg1, arg2: @arg2', array('@arg1' => $arg1, '@arg2' => $arg2));
+ // Set something to ensure that this function got called.
+ \Drupal::state()->set('_system_test_second_shutdown_function', array($arg1, $arg2));
// Throw an exception with an HTML tag. Since this is called in a shutdown
// function, it will not bubble up to the default exception handler but will
// be caught in _drupal_shutdown_function() and be displayed through
- // \Drupal\Core\Utility\Error::renderExceptionSafe().
+ // \Drupal\Core\Utility\Error::renderExceptionSafe() if possible.
throw new Exception('Drupal is .');
}