diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 755566f45b..4688c192a0 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -721,9 +721,6 @@ class FrameworkExtension extends Extension $container->setParameter('debug.error_handler.throw_at', 0); } - $definition->replaceArgument(4, $debug); - $definition->replaceArgument(6, $debug); - if ($debug && class_exists(DebugProcessor::class)) { $definition = new Definition(DebugProcessor::class); $definition->setPublic(false); diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug_prod.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug_prod.xml index 6810eadabe..e19d453d36 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug_prod.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/debug_prod.xml @@ -18,9 +18,10 @@ null %debug.error_handler.throw_at% - true + %kernel.debug% - true + %kernel.debug% + %kernel.charset% diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml index 41c682c211..fb797ff96b 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml @@ -67,16 +67,6 @@ - - - - null - null - %kernel.debug% - %kernel.charset% - %debug.file_link_format% - - diff --git a/src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php b/src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php index 6659e21793..b28ad7b83e 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php @@ -19,7 +19,10 @@ use Symfony\Component\Debug\ErrorHandler; use Symfony\Component\Debug\ExceptionHandler; use Symfony\Component\EventDispatcher\Event; use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Debug\FileLinkFormatter; +use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; use Symfony\Component\HttpKernel\Event\KernelEvent; use Symfony\Component\HttpKernel\KernelEvents; @@ -37,6 +40,7 @@ class DebugHandlersListener implements EventSubscriberInterface private $scream; private $fileLinkFormat; private $scope; + private $charset; private $firstCall = true; private $hasTerminatedWithException; @@ -49,7 +53,7 @@ class DebugHandlersListener implements EventSubscriberInterface * @param string|FileLinkFormatter|null $fileLinkFormat The format for links to source files * @param bool $scope Enables/disables scoping mode */ - public function __construct(callable $exceptionHandler = null, LoggerInterface $logger = null, $levels = E_ALL, ?int $throwAt = E_ALL, bool $scream = true, $fileLinkFormat = null, bool $scope = true) + public function __construct(callable $exceptionHandler = null, LoggerInterface $logger = null, $levels = E_ALL, ?int $throwAt = E_ALL, bool $scream = true, $fileLinkFormat = null, bool $scope = true, string $charset = null) { $this->exceptionHandler = $exceptionHandler; $this->logger = $logger; @@ -58,6 +62,7 @@ class DebugHandlersListener implements EventSubscriberInterface $this->scream = $scream; $this->fileLinkFormat = $fileLinkFormat; $this->scope = $scope; + $this->charset = $charset; } /** @@ -144,6 +149,26 @@ class DebugHandlersListener implements EventSubscriberInterface } } + /** + * @internal + */ + public function onKernelException(GetResponseForExceptionEvent $event) + { + if (!$this->hasTerminatedWithException || !$event->isMasterRequest()) { + return; + } + + $debug = $this->scream && $this->scope; + $controller = function (Request $request) use ($debug) { + $e = $request->attributes->get('exception'); + $handler = new ExceptionHandler($debug, $this->charset, $this->fileLinkFormat); + + return new Response($handler->getHtml($e), $e->getStatusCode(), $e->getHeaders()); + }; + + (new ExceptionListener($controller, $this->logger, $debug))->onKernelException($event); + } + public static function getSubscribedEvents() { $events = [KernelEvents::REQUEST => ['configure', 2048]]; @@ -152,6 +177,8 @@ class DebugHandlersListener implements EventSubscriberInterface $events[ConsoleEvents::COMMAND] = ['configure', 2048]; } + $events[KernelEvents::EXCEPTION] = ['onKernelException', -2048]; + return $events; } } diff --git a/src/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php b/src/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php index 811f99bd9d..d2b97e6627 100644 --- a/src/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php +++ b/src/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php @@ -13,11 +13,9 @@ namespace Symfony\Component\HttpKernel\EventListener; use Psr\Log\LoggerInterface; use Symfony\Component\Debug\Exception\FlattenException; -use Symfony\Component\Debug\ExceptionHandler; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\Request; -use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Event\FilterResponseEvent; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; @@ -35,17 +33,12 @@ class ExceptionListener implements EventSubscriberInterface protected $controller; protected $logger; protected $debug; - private $charset; - private $fileLinkFormat; - private $isTerminating = false; - public function __construct($controller, LoggerInterface $logger = null, $debug = false, string $charset = null, $fileLinkFormat = null) + public function __construct($controller, LoggerInterface $logger = null, $debug = false) { $this->controller = $controller; $this->logger = $logger; $this->debug = $debug; - $this->charset = $charset; - $this->fileLinkFormat = $fileLinkFormat; } public function logKernelException(GetResponseForExceptionEvent $event) @@ -58,16 +51,9 @@ class ExceptionListener implements EventSubscriberInterface public function onKernelException(GetResponseForExceptionEvent $event) { if (null === $this->controller) { - if (!$event->isMasterRequest()) { - return; - } - if (!$this->isTerminating) { - $this->isTerminating = true; - - return; - } - $this->isTerminating = false; + return; } + $exception = $event->getException(); $request = $this->duplicateRequest($exception, $event->getRequest()); $eventDispatcher = \func_num_args() > 2 ? func_get_arg(2) : null; @@ -104,11 +90,6 @@ class ExceptionListener implements EventSubscriberInterface } } - public function reset() - { - $this->isTerminating = false; - } - public static function getSubscribedEvents() { return [ @@ -147,12 +128,8 @@ class ExceptionListener implements EventSubscriberInterface protected function duplicateRequest(\Exception $exception, Request $request) { $attributes = [ - 'exception' => $exception = FlattenException::create($exception), - '_controller' => $this->controller ?: function () use ($exception) { - $handler = new ExceptionHandler($this->debug, $this->charset, $this->fileLinkFormat); - - return new Response($handler->getHtml($exception), $exception->getStatusCode(), $exception->getHeaders()); - }, + '_controller' => $this->controller, + 'exception' => FlattenException::create($exception), 'logger' => $this->logger instanceof DebugLoggerInterface ? $this->logger : null, ]; $request = $request->duplicate(null, null, $attributes); diff --git a/src/Symfony/Component/HttpKernel/Tests/EventListener/DebugHandlersListenerTest.php b/src/Symfony/Component/HttpKernel/Tests/EventListener/DebugHandlersListenerTest.php index 44af0149f7..d7077cb7e5 100644 --- a/src/Symfony/Component/HttpKernel/Tests/EventListener/DebugHandlersListenerTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/EventListener/DebugHandlersListenerTest.php @@ -104,6 +104,7 @@ class DebugHandlersListenerTest extends TestCase $xListeners = [ KernelEvents::REQUEST => [[$listener, 'configure']], ConsoleEvents::COMMAND => [[$listener, 'configure']], + KernelEvents::EXCEPTION => [[$listener, 'onKernelException']], ]; $this->assertSame($xListeners, $dispatcher->getListeners()); diff --git a/src/Symfony/Component/HttpKernel/Tests/EventListener/ExceptionListenerTest.php b/src/Symfony/Component/HttpKernel/Tests/EventListener/ExceptionListenerTest.php index 61231eb68b..bc5a8c77c8 100644 --- a/src/Symfony/Component/HttpKernel/Tests/EventListener/ExceptionListenerTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/EventListener/ExceptionListenerTest.php @@ -155,25 +155,6 @@ class ExceptionListenerTest extends TestCase $this->assertFalse($response->headers->has('content-security-policy'), 'CSP header has been removed'); $this->assertFalse($dispatcher->hasListeners(KernelEvents::RESPONSE), 'CSP removal listener has been removed'); } - - public function testNullController() - { - $listener = new ExceptionListener(null); - $kernel = $this->getMockBuilder(HttpKernelInterface::class)->getMock(); - $kernel->expects($this->once())->method('handle')->willReturnCallback(function (Request $request) { - $controller = $request->attributes->get('_controller'); - - return $controller(); - }); - $request = Request::create('/'); - $event = new GetResponseForExceptionEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST, new \Exception('foo')); - - $listener->onKernelException($event); - $this->assertNull($event->getResponse()); - - $listener->onKernelException($event); - $this->assertContains('Whoops, looks like something went wrong.', $event->getResponse()->getContent()); - } } class TestLogger extends Logger implements DebugLoggerInterface