From a40a292796a4d90a3073afeb956fe1a151e94fbb Mon Sep 17 00:00:00 2001 From: Thomas Calvet Date: Sun, 13 Jan 2019 13:45:12 +0100 Subject: [PATCH] [Debug][ErrorHandler] Preserve our error handler when a logger set another one --- src/Symfony/Component/Debug/ErrorHandler.php | 1 + .../Debug/Tests/ErrorHandlerTest.php | 44 +++++++++++++++++++ .../Fixtures/LoggerThatSetAnErrorHandler.php | 14 ++++++ 3 files changed, 59 insertions(+) create mode 100644 src/Symfony/Component/Debug/Tests/Fixtures/LoggerThatSetAnErrorHandler.php diff --git a/src/Symfony/Component/Debug/ErrorHandler.php b/src/Symfony/Component/Debug/ErrorHandler.php index 64857ed447228..b05ce9cd75495 100644 --- a/src/Symfony/Component/Debug/ErrorHandler.php +++ b/src/Symfony/Component/Debug/ErrorHandler.php @@ -523,6 +523,7 @@ public function handleError($type, $message, $file, $line) $this->loggers[$type][0]->log($level, $logMessage, $errorAsException ? ['exception' => $errorAsException] : []); } finally { $this->isRecursive = false; + set_error_handler([$this, __FUNCTION__]); } } diff --git a/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php b/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php index 98d9f6143da0c..6e0afd55cacf0 100644 --- a/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php +++ b/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php @@ -12,10 +12,13 @@ namespace Symfony\Component\Debug\Tests; use PHPUnit\Framework\TestCase; +use Psr\Log\LoggerInterface; use Psr\Log\LogLevel; +use Psr\Log\NullLogger; use Symfony\Component\Debug\BufferingLogger; use Symfony\Component\Debug\ErrorHandler; use Symfony\Component\Debug\Exception\SilencedErrorContext; +use Symfony\Component\Debug\Tests\Fixtures\LoggerThatSetAnErrorHandler; /** * ErrorHandlerTest. @@ -321,6 +324,8 @@ public function testHandleDeprecation() $handler = new ErrorHandler(); $handler->setDefaultLogger($logger); @$handler->handleError(E_USER_DEPRECATED, 'Foo deprecation', __FILE__, __LINE__, []); + + restore_error_handler(); } /** @@ -583,4 +588,43 @@ public function testCustomExceptionHandler() $handler->handleException(new \Exception()); } + + /** + * @dataProvider errorHandlerIsNotLostWhenLoggingProvider + */ + public function testErrorHandlerIsNotLostWhenLogging($customErrorHandlerHasBeenPreviouslyDefined, LoggerInterface $logger) + { + try { + if ($customErrorHandlerHasBeenPreviouslyDefined) { + set_error_handler('count'); + } + + $handler = ErrorHandler::register(); + $handler->setDefaultLogger($logger); + + @trigger_error('foo', E_USER_DEPRECATED); + @trigger_error('bar', E_USER_DEPRECATED); + + $this->assertSame([$handler, 'handleError'], set_error_handler('var_dump')); + + restore_error_handler(); + + if ($customErrorHandlerHasBeenPreviouslyDefined) { + restore_error_handler(); + } + } finally { + restore_error_handler(); + restore_exception_handler(); + } + } + + public function errorHandlerIsNotLostWhenLoggingProvider() + { + return [ + [false, new NullLogger()], + [true, new NullLogger()], + [false, new LoggerThatSetAnErrorHandler()], + [true, new LoggerThatSetAnErrorHandler()], + ]; + } } diff --git a/src/Symfony/Component/Debug/Tests/Fixtures/LoggerThatSetAnErrorHandler.php b/src/Symfony/Component/Debug/Tests/Fixtures/LoggerThatSetAnErrorHandler.php new file mode 100644 index 0000000000000..7545039cf85a4 --- /dev/null +++ b/src/Symfony/Component/Debug/Tests/Fixtures/LoggerThatSetAnErrorHandler.php @@ -0,0 +1,14 @@ +