diff --git a/src/Symfony/Component/ErrorHandler/ErrorHandler.php b/src/Symfony/Component/ErrorHandler/ErrorHandler.php index bda939a828073..0afc44a28a462 100644 --- a/src/Symfony/Component/ErrorHandler/ErrorHandler.php +++ b/src/Symfony/Component/ErrorHandler/ErrorHandler.php @@ -516,14 +516,7 @@ public function handleException(\Throwable $exception): void } } - if (!$exception instanceof OutOfMemoryError) { - foreach ($this->getErrorEnhancers() as $errorEnhancer) { - if ($e = $errorEnhancer->enhance($exception)) { - $exception = $e; - break; - } - } - } + $exception = $this->enhanceError($exception); $exceptionHandler = $this->exceptionHandler; $this->exceptionHandler = [$this, 'renderException']; @@ -661,6 +654,21 @@ private function renderException(\Throwable $exception): void echo $exception->getAsString(); } + public function enhanceError(\Throwable $exception): \Throwable + { + if ($exception instanceof OutOfMemoryError) { + return $exception; + } + + foreach ($this->getErrorEnhancers() as $errorEnhancer) { + if ($e = $errorEnhancer->enhance($exception)) { + return $e; + } + } + + return $exception; + } + /** * Override this method if you want to define more error enhancers. * diff --git a/src/Symfony/Component/ErrorHandler/Tests/ErrorHandlerTest.php b/src/Symfony/Component/ErrorHandler/Tests/ErrorHandlerTest.php index e407dd4966eba..1e48e8a910b6b 100644 --- a/src/Symfony/Component/ErrorHandler/Tests/ErrorHandlerTest.php +++ b/src/Symfony/Component/ErrorHandler/Tests/ErrorHandlerTest.php @@ -363,13 +363,14 @@ public function testHandleDeprecation() /** * @dataProvider handleExceptionProvider */ - public function testHandleException(string $expectedMessage, \Throwable $exception) + public function testHandleException(string $expectedMessage, \Throwable $exception, string $enhancedMessage = null) { try { $logger = $this->createMock(LoggerInterface::class); $handler = ErrorHandler::register(); $logArgCheck = function ($level, $message, $context) use ($expectedMessage, $exception) { + $this->assertSame('critical', $level); $this->assertSame($expectedMessage, $message); $this->assertArrayHasKey('exception', $context); $this->assertInstanceOf($exception::class, $context['exception']); @@ -388,11 +389,13 @@ public function testHandleException(string $expectedMessage, \Throwable $excepti $handler->handleException($exception); $this->fail('Exception expected'); } catch (\Throwable $e) { - $this->assertSame($exception, $e); + $this->assertInstanceOf($exception::class, $e); + $this->assertSame($enhancedMessage ?? $exception->getMessage(), $e->getMessage()); } - $handler->setExceptionHandler(function ($e) use ($exception) { - $this->assertSame($exception, $e); + $handler->setExceptionHandler(function ($e) use ($exception, $enhancedMessage) { + $this->assertInstanceOf($exception::class, $e); + $this->assertSame($enhancedMessage ?? $exception->getMessage(), $e->getMessage()); }); $handler->handleException($exception); @@ -412,6 +415,11 @@ public static function handleExceptionProvider(): array })::class.' bar')], ['Uncaught Error: bar', new \Error('bar')], ['Uncaught ccc', new \ErrorException('ccc')], + [ + 'Uncaught Error: Class "App\Controller\ClassDoesNotExist" not found', + new \Error('Class "App\Controller\ClassDoesNotExist" not found'), + "Attempted to load class \"ClassDoesNotExist\" from namespace \"App\Controller\".\nDid you forget a \"use\" statement for another namespace?", + ], ]; } diff --git a/src/Symfony/Component/HttpKernel/EventListener/ErrorListener.php b/src/Symfony/Component/HttpKernel/EventListener/ErrorListener.php index cc6936cfda963..3ecd04a2abdf6 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/ErrorListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/ErrorListener.php @@ -13,6 +13,7 @@ use Psr\Log\LoggerInterface; use Psr\Log\LogLevel; +use Symfony\Component\ErrorHandler\ErrorHandler; use Symfony\Component\ErrorHandler\Exception\FlattenException; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\Request; @@ -102,6 +103,14 @@ public function onKernelException(ExceptionEvent $event) } $throwable = $event->getThrowable(); + + if ($exceptionHandler = set_exception_handler(var_dump(...))) { + restore_exception_handler(); + if (\is_array($exceptionHandler) && $exceptionHandler[0] instanceof ErrorHandler) { + $throwable = $exceptionHandler[0]->enhanceError($event->getThrowable()); + } + } + $request = $this->duplicateRequest($throwable, $event->getRequest()); try { diff --git a/src/Symfony/Component/HttpKernel/composer.json b/src/Symfony/Component/HttpKernel/composer.json index 0d948e3275f44..829dd8f81657b 100644 --- a/src/Symfony/Component/HttpKernel/composer.json +++ b/src/Symfony/Component/HttpKernel/composer.json @@ -18,7 +18,7 @@ "require": { "php": ">=8.1", "symfony/deprecation-contracts": "^2.5|^3", - "symfony/error-handler": "^6.3|^7.0", + "symfony/error-handler": "^6.4|^7.0", "symfony/event-dispatcher": "^5.4|^6.0|^7.0", "symfony/http-foundation": "^6.2.7|^7.0", "symfony/polyfill-ctype": "^1.8",