diff --git a/src/Symfony/Component/Debug/ErrorHandler.php b/src/Symfony/Component/Debug/ErrorHandler.php index 22a6426dab7e9..726c150d4fdf3 100644 --- a/src/Symfony/Component/Debug/ErrorHandler.php +++ b/src/Symfony/Component/Debug/ErrorHandler.php @@ -517,6 +517,11 @@ public function handleError($type, $message, $file, $line) $errorAsException ? ['exception' => $errorAsException] : [], ]; } else { + if (!$hhvm = \defined('HHVM_VERSION')) { + $currentErrorHandler = set_error_handler('var_dump'); + restore_error_handler(); + } + try { $this->isRecursive = true; $level = ($type & $level) ? $this->loggers[$type][1] : LogLevel::DEBUG; @@ -524,8 +529,8 @@ public function handleError($type, $message, $file, $line) } finally { $this->isRecursive = false; - if (!\defined('HHVM_VERSION')) { - set_error_handler([$this, __FUNCTION__]); + if (!$hhvm) { + set_error_handler($currentErrorHandler); } } } diff --git a/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php b/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php index 6e0afd55cacf0..d1c5e408f5aaa 100644 --- a/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php +++ b/src/Symfony/Component/Debug/Tests/ErrorHandlerTest.php @@ -18,6 +18,7 @@ use Symfony\Component\Debug\BufferingLogger; use Symfony\Component\Debug\ErrorHandler; use Symfony\Component\Debug\Exception\SilencedErrorContext; +use Symfony\Component\Debug\Tests\Fixtures\ErrorHandlerThatUsesThePreviousOne; use Symfony\Component\Debug\Tests\Fixtures\LoggerThatSetAnErrorHandler; /** @@ -590,26 +591,40 @@ public function testCustomExceptionHandler() } /** - * @dataProvider errorHandlerIsNotLostWhenLoggingProvider + * @dataProvider errorHandlerWhenLoggingProvider */ - public function testErrorHandlerIsNotLostWhenLogging($customErrorHandlerHasBeenPreviouslyDefined, LoggerInterface $logger) + public function testErrorHandlerWhenLogging($previousHandlerWasDefined, $loggerSetsAnotherHandler, $nextHandlerIsDefined) { try { - if ($customErrorHandlerHasBeenPreviouslyDefined) { + if ($previousHandlerWasDefined) { set_error_handler('count'); } + $logger = $loggerSetsAnotherHandler ? new LoggerThatSetAnErrorHandler() : new NullLogger(); + $handler = ErrorHandler::register(); $handler->setDefaultLogger($logger); + if ($nextHandlerIsDefined) { + $handler = ErrorHandlerThatUsesThePreviousOne::register(); + } + @trigger_error('foo', E_USER_DEPRECATED); @trigger_error('bar', E_USER_DEPRECATED); $this->assertSame([$handler, 'handleError'], set_error_handler('var_dump')); + if ($logger instanceof LoggerThatSetAnErrorHandler) { + $this->assertCount(2, $logger->cleanLogs()); + } + restore_error_handler(); - if ($customErrorHandlerHasBeenPreviouslyDefined) { + if ($previousHandlerWasDefined) { + restore_error_handler(); + } + + if ($nextHandlerIsDefined) { restore_error_handler(); } } finally { @@ -618,13 +633,14 @@ public function testErrorHandlerIsNotLostWhenLogging($customErrorHandlerHasBeenP } } - public function errorHandlerIsNotLostWhenLoggingProvider() + public function errorHandlerWhenLoggingProvider() { - return [ - [false, new NullLogger()], - [true, new NullLogger()], - [false, new LoggerThatSetAnErrorHandler()], - [true, new LoggerThatSetAnErrorHandler()], - ]; + foreach ([false, true] as $previousHandlerWasDefined) { + foreach ([false, true] as $loggerSetsAnotherHandler) { + foreach ([false, true] as $nextHandlerIsDefined) { + yield [$previousHandlerWasDefined, $loggerSetsAnotherHandler, $nextHandlerIsDefined]; + } + } + } } } diff --git a/src/Symfony/Component/Debug/Tests/Fixtures/ErrorHandlerThatUsesThePreviousOne.php b/src/Symfony/Component/Debug/Tests/Fixtures/ErrorHandlerThatUsesThePreviousOne.php new file mode 100644 index 0000000000000..e425a952510d8 --- /dev/null +++ b/src/Symfony/Component/Debug/Tests/Fixtures/ErrorHandlerThatUsesThePreviousOne.php @@ -0,0 +1,29 @@ +