Commit 98459991 authored by alexpott's avatar alexpott

Issue #2540438 by znerol, timmillwood: Invalid format string when falling back...

Issue #2540438 by znerol, timmillwood: Invalid format string when falling back to error_log in _drupal_log_error()
parent 9a7b71ad
......@@ -159,7 +159,7 @@ function _drupal_log_error($error, $fatal = FALSE) {
catch (\Exception $e) {
// We can't log, for example because the database connection is not
// available. At least try to log to PHP error log.
error_log(sprintf('Failed to log error: %type: !message in %function (line %line of %file).', $error['%type'], $error['%function'], $error['%line'], $error['%file']));
error_log(strtr('Failed to log error: %type: !message in %function (line %line of %file).', $error));
}
}
......
......@@ -185,6 +185,35 @@ public function testLostDatabaseConnection() {
$this->assertRaw('PDOException');
}
/**
* Tests fallback to PHP error log when an exception is thrown while logging.
*/
public function testLoggerException() {
// Ensure the test error log is empty before these tests.
$this->assertNoErrorsLogged();
$this->expectedExceptionMessage = 'Deforestation';
\Drupal::state()->set('error_service_test.break_logger', TRUE);
$this->drupalGet('');
$this->assertResponse(500);
$this->assertText('The website encountered an unexpected error. Please try again later.');
$this->assertRaw($this->expectedExceptionMessage);
// Find fatal error logged to the simpletest error.log
$errors = file(\Drupal::root() . '/' . $this->siteDirectory . '/error.log');
$this->assertIdentical(count($errors), 1, 'Exactly one line logged to the PHP error log');
$expected_path = \Drupal::root() . '/core/modules/system/tests/modules/error_service_test/src/MonkeysInTheControlRoom.php';
$expected_line = 61;
$expected_entry = "Failed to log error: Exception: Deforestation in Drupal\\error_service_test\\MonkeysInTheControlRoom->handle() (line ${expected_line} of ${expected_path})";
$this->assert(strpos($errors[0], $expected_entry) !== FALSE, 'Original error logged to the PHP error log when an exception is thrown by a logger');
// The exception is expected. Do not interpret it as a test failure. Not
// using File API; a potential error must trigger a PHP warning.
unlink(\Drupal::root() . '/' . $this->siteDirectory . '/error.log');
}
/**
* {@inheritdoc}
*/
......
......@@ -6,3 +6,8 @@ services:
# Set up a service with a missing class dependency.
broken_class_with_missing_dependency:
class: Drupal\error_service_test\LonelyMonkeyClass
logger.broken:
class: Drupal\error_service_test\Logger\TestLog
tags:
- { name: logger }
- { name: backend_overridable }
<?php
/**
* @file
* Contains \Drupal\error_service_test\Logger\TestLog.
*/
namespace Drupal\error_service_test\Logger;
use Drupal\Core\Logger\RfcLoggerTrait;
use Psr\Log\LoggerInterface;
/**
* Throws an exception while logging an exception.
*
* @see \Drupal\system\Tests\System\UncaughtExceptionTest::testLoggerException()
*/
class TestLog implements LoggerInterface {
use RfcLoggerTrait;
/**
* {@inheritdoc}
*/
public function log($level, $message, array $context = array()) {
$trigger = [
'%type' => 'Exception',
'!message' => 'Deforestation',
'%function' => 'Drupal\error_service_test\MonkeysInTheControlRoom->handle()',
'severity_level' => 3,
'channel' => 'php',
];
if (array_diff_assoc($trigger, $context) === []) {
throw new \Exception('Oh, oh, frustrated monkeys!');
}
}
}
......@@ -57,6 +57,10 @@ public function handle(Request $request, $type = self::MASTER_REQUEST, $catch =
throw new \Exception('Oh oh, bananas in the instruments.');
}
if (\Drupal::state()->get('error_service_test.break_logger')) {
throw new \Exception('Deforestation');
}
return $this->app->handle($request, $type, $catch);
}
......
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