diff --git a/src/Symfony/EventListener/ErrorListener.php b/src/Symfony/EventListener/ErrorListener.php index c0eab7879dc..011f886c57f 100644 --- a/src/Symfony/EventListener/ErrorListener.php +++ b/src/Symfony/EventListener/ErrorListener.php @@ -80,9 +80,11 @@ protected function duplicateRequest(\Throwable $exception, Request $request): Re // Let the error handler take this we don't handle HTML nor non-api platform requests if (false === ($apiOperation?->getExtraProperties()['_api_error_handler'] ?? true) || 'html' === $format) { - $this->controller = 'error_controller'; + $dup = parent::duplicateRequest($exception, $request); + // Override parent's `_controller` attribute without mutating $this->controller (worker-mode safety). + $dup->attributes->set('_controller', 'error_controller'); - return parent::duplicateRequest($exception, $request); + return $dup; } if ($this->debug) { @@ -90,6 +92,7 @@ protected function duplicateRequest(\Throwable $exception, Request $request): Re } $dup = parent::duplicateRequest($exception, $request); + $operation = $this->initializeExceptionOperation($request, $exception, $format, $apiOperation); if (null === $operation->getProvider()) { diff --git a/src/Symfony/Tests/EventListener/ErrorListenerTest.php b/src/Symfony/Tests/EventListener/ErrorListenerTest.php index 09b8a990248..effa85bb103 100644 --- a/src/Symfony/Tests/EventListener/ErrorListenerTest.php +++ b/src/Symfony/Tests/EventListener/ErrorListenerTest.php @@ -142,4 +142,26 @@ public function testDuplicateExceptionWithErrorResource(): void $errorListener = new ErrorListener('action', null, true, [], $resourceMetadataCollectionFactory, ['jsonld' => ['application/ld+json']], [], $identifiersExtractor, $resourceClassResolver); $errorListener->onKernelException($exceptionEvent); } + + public function testStateIsNeverModified(): void + { + $resourceClassResolver = $this->createStub(ResourceClassResolverInterface::class); + $kernel = $this->createStub(KernelInterface::class); + $kernel->method('handle')->willReturn(new Response()); + + $request = Request::create('/'); + $request->headers->set('Accept', 'text/html'); + $exception = new \Exception(); + $exceptionEvent = new ExceptionEvent($kernel, $request, HttpKernelInterface::SUB_REQUEST, $exception); + + $initialController = 'initial_controller'; + $errorListener = new ErrorListener($initialController, null, false, [], null, ['jsonproblem' => ['application/problem+json']], [], null, $resourceClassResolver); + + $errorListener->onKernelException($exceptionEvent); + + $refl = new \ReflectionClass($errorListener); + $controllerProp = $refl->getProperty('controller'); + + $this->assertEquals($initialController, $controllerProp->getValue($errorListener), 'The controller property must never be modified.'); + } }