*
- * @deprecated since Symfony 4.4, use Symfony\Component\ErrorHandler\Exception\ErrorException instead.
+ * @deprecated since Symfony 4.4, use Symfony\Component\ErrorHandler\Error\FatalError instead.
*/
class FatalErrorException extends \ErrorException
{
diff --git a/src/Symfony/Component/Debug/Exception/FatalThrowableError.php b/src/Symfony/Component/Debug/Exception/FatalThrowableError.php
index 53c410b014b1d..e13b0172f0588 100644
--- a/src/Symfony/Component/Debug/Exception/FatalThrowableError.php
+++ b/src/Symfony/Component/Debug/Exception/FatalThrowableError.php
@@ -11,14 +11,14 @@
namespace Symfony\Component\Debug\Exception;
-@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', FatalThrowableError::class, \Symfony\Component\ErrorHandler\Exception\ErrorException::class), E_USER_DEPRECATED);
+@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4.', FatalThrowableError::class), E_USER_DEPRECATED);
/**
* Fatal Throwable Error.
*
* @author Nicolas Grekas
*
- * @deprecated since Symfony 4.4, use Symfony\Component\ErrorHandler\Exception\ErrorException instead.
+ * @deprecated since Symfony 4.4
*/
class FatalThrowableError extends FatalErrorException
{
diff --git a/src/Symfony/Component/ErrorHandler/Exception/ErrorException.php b/src/Symfony/Component/ErrorHandler/Exception/ErrorException.php
deleted file mode 100644
index 759d3fdc47a3f..0000000000000
--- a/src/Symfony/Component/ErrorHandler/Exception/ErrorException.php
+++ /dev/null
@@ -1,42 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\ErrorHandler\Exception;
-
-use Symfony\Component\ErrorHandler\ThrowableUtils;
-
-class ErrorException extends \ErrorException
-{
- private $originalClassName;
-
- public function __construct(\Throwable $e)
- {
- $this->originalClassName = \get_class($e);
-
- parent::__construct(
- $e->getMessage(),
- $e->getCode(),
- ThrowableUtils::getSeverity($e),
- $e->getFile(),
- $e->getLine(),
- $e->getPrevious()
- );
-
- $refl = new \ReflectionProperty(\Exception::class, 'trace');
- $refl->setAccessible(true);
- $refl->setValue($this, $e->getTrace());
- }
-
- public function getOriginalClassName(): string
- {
- return $this->originalClassName;
- }
-}
diff --git a/src/Symfony/Component/ErrorRenderer/Exception/FlattenException.php b/src/Symfony/Component/ErrorRenderer/Exception/FlattenException.php
index da3454e05eb04..dd86f5b74bb07 100644
--- a/src/Symfony/Component/ErrorRenderer/Exception/FlattenException.php
+++ b/src/Symfony/Component/ErrorRenderer/Exception/FlattenException.php
@@ -12,7 +12,6 @@
namespace Symfony\Component\ErrorRenderer\Exception;
use Symfony\Component\Debug\Exception\FlattenException as LegacyFlattenException;
-use Symfony\Component\ErrorHandler\Exception\ErrorException;
use Symfony\Component\HttpFoundation\Exception\RequestExceptionInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
@@ -70,7 +69,7 @@ public static function createFromThrowable(\Throwable $exception, int $statusCod
$e->setStatusCode($statusCode);
$e->setHeaders($headers);
$e->setTraceFromThrowable($exception);
- $e->setClass($exception instanceof ErrorException ? $exception->getOriginalClassName() : \get_class($exception));
+ $e->setClass(\get_class($exception));
$e->setFile($exception->getFile());
$e->setLine($exception->getLine());
diff --git a/src/Symfony/Component/ErrorRenderer/Tests/Exception/FlattenExceptionTest.php b/src/Symfony/Component/ErrorRenderer/Tests/Exception/FlattenExceptionTest.php
index dc2678be8158a..dad78d152540d 100644
--- a/src/Symfony/Component/ErrorRenderer/Tests/Exception/FlattenExceptionTest.php
+++ b/src/Symfony/Component/ErrorRenderer/Tests/Exception/FlattenExceptionTest.php
@@ -12,7 +12,6 @@
namespace Symfony\Component\ErrorRenderer\Tests\Exception;
use PHPUnit\Framework\TestCase;
-use Symfony\Component\ErrorHandler\Exception\ErrorException;
use Symfony\Component\ErrorRenderer\Exception\FlattenException;
use Symfony\Component\HttpFoundation\Exception\SuspiciousOperationException;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
@@ -130,16 +129,6 @@ public function testFlattenHttpException(\Throwable $exception)
$this->assertInstanceOf($flattened->getClass(), $exception, 'The class is set to the class of the original exception');
}
- public function testWrappedThrowable()
- {
- $exception = new ErrorException(new \DivisionByZeroError('Ouch', 42));
- $flattened = FlattenException::createFromThrowable($exception);
-
- $this->assertSame('Ouch', $flattened->getMessage(), 'The message is copied from the original error.');
- $this->assertSame(42, $flattened->getCode(), 'The code is copied from the original error.');
- $this->assertSame('DivisionByZeroError', $flattened->getClass(), 'The class is set to the class of the original error');
- }
-
public function testThrowable()
{
$error = new \DivisionByZeroError('Ouch', 42);
diff --git a/src/Symfony/Component/HttpKernel/CHANGELOG.md b/src/Symfony/Component/HttpKernel/CHANGELOG.md
index 28af7d7fc0a92..08a8cfddd7332 100644
--- a/src/Symfony/Component/HttpKernel/CHANGELOG.md
+++ b/src/Symfony/Component/HttpKernel/CHANGELOG.md
@@ -21,6 +21,8 @@ CHANGELOG
* Marked the `RouterDataCollector::collect()` method as `@final`.
* The `DataCollectorInterface::collect()` and `Profiler::collect()` methods third parameter signature
will be `\Throwable $exception = null` instead of `\Exception $exception = null` in Symfony 5.0.
+ * Deprecated methods `ExceptionEvent::get/setException()`, use `get/setThrowable()` instead
+ * Deprecated class `ExceptionListener`, use `ErrorListener` instead
4.3.0
-----
diff --git a/src/Symfony/Component/HttpKernel/Controller/ErrorController.php b/src/Symfony/Component/HttpKernel/Controller/ErrorController.php
index 4d58a61120cd0..a86fa5c5cf391 100644
--- a/src/Symfony/Component/HttpKernel/Controller/ErrorController.php
+++ b/src/Symfony/Component/HttpKernel/Controller/ErrorController.php
@@ -52,7 +52,7 @@ public function preview(Request $request, int $code): Response
/*
* This Request mimics the parameters set by
- * \Symfony\Component\HttpKernel\EventListener\ExceptionListener::duplicateRequest, with
+ * \Symfony\Component\HttpKernel\EventListener\ErrorListener::duplicateRequest, with
* the additional "showException" flag.
*/
$subRequest = $request->duplicate(null, null, [
diff --git a/src/Symfony/Component/HttpKernel/Event/GetResponseForExceptionEvent.php b/src/Symfony/Component/HttpKernel/Event/GetResponseForExceptionEvent.php
index 3476c7e62a0cc..8b238f0db94dc 100644
--- a/src/Symfony/Component/HttpKernel/Event/GetResponseForExceptionEvent.php
+++ b/src/Symfony/Component/HttpKernel/Event/GetResponseForExceptionEvent.php
@@ -19,45 +19,55 @@
*/
class GetResponseForExceptionEvent extends RequestEvent
{
- /**
- * The exception object.
- *
- * @var \Exception
- */
+ private $throwable;
private $exception;
-
- /**
- * @var bool
- */
private $allowCustomResponseCode = false;
- public function __construct(HttpKernelInterface $kernel, Request $request, int $requestType, \Exception $e)
+ public function __construct(HttpKernelInterface $kernel, Request $request, int $requestType, \Throwable $e)
{
parent::__construct($kernel, $request, $requestType);
- $this->setException($e);
+ $this->setThrowable($e);
+ }
+
+ public function getThrowable(): \Throwable
+ {
+ return $this->throwable;
+ }
+
+ /**
+ * Replaces the thrown exception.
+ *
+ * This exception will be thrown if no response is set in the event.
+ */
+ public function setThrowable(\Throwable $exception): void
+ {
+ $this->exception = null;
+ $this->throwable = $exception;
}
/**
- * Returns the thrown exception.
+ * @deprecated since Symfony 4.4, use getThrowable instead
*
* @return \Exception The thrown exception
*/
public function getException()
{
- return $this->exception;
+ @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.4, use "getThrowable()" instead.', __METHOD__), E_USER_DEPRECATED);
+
+ return $this->exception ?? $this->exception = $this->throwable instanceof \Exception ? $this->throwable : new FatalThrowableError($this->throwable);
}
/**
- * Replaces the thrown exception.
- *
- * This exception will be thrown if no response is set in the event.
+ * @deprecated since Symfony 4.4, use setThrowable instead
*
* @param \Exception $exception The thrown exception
*/
public function setException(\Exception $exception)
{
- $this->exception = $exception;
+ @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.4, use "setThrowable()" instead.', __METHOD__), E_USER_DEPRECATED);
+
+ $this->throwable = $this->exception = $exception;
}
/**
diff --git a/src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php b/src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php
index 9779431eb9d03..8ed6a10e528a1 100644
--- a/src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php
+++ b/src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php
@@ -15,8 +15,8 @@
use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\Console\Event\ConsoleEvent;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
+use Symfony\Component\Debug\Exception\FatalThrowableError;
use Symfony\Component\ErrorHandler\ErrorHandler;
-use Symfony\Component\ErrorHandler\Exception\ErrorException;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Debug\FileLinkFormatter;
@@ -112,10 +112,6 @@ public function configure(Event $event = null)
throw $e;
}
- if (!$e instanceof \Exception) {
- $e = new ErrorException($e);
- }
-
$hasRun = true;
$kernel->terminateWithException($e, $request);
};
@@ -130,7 +126,7 @@ public function configure(Event $event = null)
$app->renderThrowable($e, $output);
} else {
if (!$e instanceof \Exception) {
- $e = new ErrorException($e);
+ $e = new FatalThrowableError($e);
}
$app->renderException($e, $output);
diff --git a/src/Symfony/Component/HttpKernel/EventListener/ErrorListener.php b/src/Symfony/Component/HttpKernel/EventListener/ErrorListener.php
new file mode 100644
index 0000000000000..9a16cde741432
--- /dev/null
+++ b/src/Symfony/Component/HttpKernel/EventListener/ErrorListener.php
@@ -0,0 +1,134 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpKernel\EventListener;
+
+use Psr\Log\LoggerInterface;
+use Symfony\Component\ErrorRenderer\Exception\FlattenException;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpKernel\Event\ExceptionEvent;
+use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
+use Symfony\Component\HttpKernel\HttpKernelInterface;
+use Symfony\Component\HttpKernel\KernelEvents;
+use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
+
+/**
+ * @author Fabien Potencier
+ */
+class ErrorListener implements EventSubscriberInterface
+{
+ protected $controller;
+ protected $logger;
+ protected $debug;
+
+ public function __construct($controller, LoggerInterface $logger = null, $debug = false)
+ {
+ $this->controller = $controller;
+ $this->logger = $logger;
+ $this->debug = $debug;
+ }
+
+ public function logKernelException(ExceptionEvent $event)
+ {
+ $e = FlattenException::createFromThrowable($event->getThrowable());
+
+ $this->logException($event->getThrowable(), sprintf('Uncaught PHP Exception %s: "%s" at %s line %s', $e->getClass(), $e->getMessage(), $e->getFile(), $e->getLine()));
+ }
+
+ public function onKernelException(ExceptionEvent $event)
+ {
+ if (null === $this->controller) {
+ return;
+ }
+
+ $exception = $event->getThrowable();
+ $request = $this->duplicateRequest($exception, $event->getRequest());
+ $eventDispatcher = \func_num_args() > 2 ? func_get_arg(2) : null;
+
+ try {
+ $response = $event->getKernel()->handle($request, HttpKernelInterface::SUB_REQUEST, false);
+ } catch (\Exception $e) {
+ $f = FlattenException::createFromThrowable($e);
+
+ $this->logException($e, sprintf('Exception thrown when handling an exception (%s: %s at %s line %s)', $f->getClass(), $f->getMessage(), $e->getFile(), $e->getLine()));
+
+ $prev = $e;
+ do {
+ if ($exception === $wrapper = $prev) {
+ throw $e;
+ }
+ } while ($prev = $wrapper->getPrevious());
+
+ $prev = new \ReflectionProperty($wrapper instanceof \Exception ? \Exception::class : \Error::class, 'previous');
+ $prev->setAccessible(true);
+ $prev->setValue($wrapper, $exception);
+
+ throw $e;
+ }
+
+ $event->setResponse($response);
+
+ if ($this->debug && $eventDispatcher instanceof EventDispatcherInterface) {
+ $cspRemovalListener = function ($event) use (&$cspRemovalListener, $eventDispatcher) {
+ $event->getResponse()->headers->remove('Content-Security-Policy');
+ $eventDispatcher->removeListener(KernelEvents::RESPONSE, $cspRemovalListener);
+ };
+ $eventDispatcher->addListener(KernelEvents::RESPONSE, $cspRemovalListener, -128);
+ }
+ }
+
+ public static function getSubscribedEvents()
+ {
+ return [
+ KernelEvents::EXCEPTION => [
+ ['logKernelException', 0],
+ ['onKernelException', -128],
+ ],
+ ];
+ }
+
+ /**
+ * Logs an exception.
+ *
+ * @param \Exception $exception The \Exception instance
+ * @param string $message The error message to log
+ */
+ protected function logException(\Exception $exception, $message)
+ {
+ if (null !== $this->logger) {
+ if (!$exception instanceof HttpExceptionInterface || $exception->getStatusCode() >= 500) {
+ $this->logger->critical($message, ['exception' => $exception]);
+ } else {
+ $this->logger->error($message, ['exception' => $exception]);
+ }
+ }
+ }
+
+ /**
+ * Clones the request for the exception.
+ *
+ * @return Request The cloned request
+ */
+ protected function duplicateRequest(\Exception $exception, Request $request)
+ {
+ $attributes = [
+ '_controller' => $this->controller,
+ 'exception' => FlattenException::createFromThrowable($exception),
+ 'logger' => $this->logger instanceof DebugLoggerInterface ? $this->logger : null,
+ ];
+ $request = $request->duplicate(null, null, $attributes);
+ $request->setMethod('GET');
+
+ return $request;
+ }
+}
diff --git a/src/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php b/src/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php
index ae64374c6efb4..dc2fd818ce93a 100644
--- a/src/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php
+++ b/src/Symfony/Component/HttpKernel/EventListener/ExceptionListener.php
@@ -22,10 +22,10 @@
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
+@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "ErrorListener" instead.', ExceptionListener::class), E_USER_DEPRECATED);
+
/**
- * @author Fabien Potencier
- *
- * @final since Symfony 4.3
+ * @deprecated since Symfony 4.4, use ErrorListener instead
*/
class ExceptionListener implements EventSubscriberInterface
{
diff --git a/src/Symfony/Component/HttpKernel/EventListener/ProfilerListener.php b/src/Symfony/Component/HttpKernel/EventListener/ProfilerListener.php
index f9db55211ea83..b8464f1627353 100644
--- a/src/Symfony/Component/HttpKernel/EventListener/ProfilerListener.php
+++ b/src/Symfony/Component/HttpKernel/EventListener/ProfilerListener.php
@@ -62,7 +62,7 @@ public function onKernelException(GetResponseForExceptionEvent $event)
return;
}
- $this->exception = $event->getException();
+ $this->exception = $event->getThrowable();
}
/**
diff --git a/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php b/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php
index 9d8e83bc71e08..ee88debae45e8 100644
--- a/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php
+++ b/src/Symfony/Component/HttpKernel/EventListener/RouterListener.php
@@ -143,7 +143,7 @@ public function onKernelRequest(GetResponseEvent $event)
public function onKernelException(GetResponseForExceptionEvent $event)
{
- if (!$this->debug || !($e = $event->getException()) instanceof NotFoundHttpException) {
+ if (!$this->debug || !($e = $event->getThrowable()) instanceof NotFoundHttpException) {
return;
}
diff --git a/src/Symfony/Component/HttpKernel/HttpKernel.php b/src/Symfony/Component/HttpKernel/HttpKernel.php
index 02b35e31ec510..c4cc3a3cc41c5 100644
--- a/src/Symfony/Component/HttpKernel/HttpKernel.php
+++ b/src/Symfony/Component/HttpKernel/HttpKernel.php
@@ -207,7 +207,7 @@ private function handleThrowable(\Throwable $e, Request $request, int $type): Re
$this->dispatcher->dispatch($event, KernelEvents::EXCEPTION);
// a listener might have replaced the exception
- $e = $event->getException();
+ $e = $event->getThrowable();
if (!$event->hasResponse()) {
$this->finishRequest($request, $type);
diff --git a/src/Symfony/Component/HttpKernel/Tests/EventListener/ErrorListenerTest.php b/src/Symfony/Component/HttpKernel/Tests/EventListener/ErrorListenerTest.php
new file mode 100644
index 0000000000000..3707f3c4c920e
--- /dev/null
+++ b/src/Symfony/Component/HttpKernel/Tests/EventListener/ErrorListenerTest.php
@@ -0,0 +1,180 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpKernel\Tests\EventListener;
+
+use PHPUnit\Framework\TestCase;
+use Symfony\Component\EventDispatcher\EventDispatcher;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\Event\ExceptionEvent;
+use Symfony\Component\HttpKernel\Event\ResponseEvent;
+use Symfony\Component\HttpKernel\EventListener\ErrorListener;
+use Symfony\Component\HttpKernel\HttpKernelInterface;
+use Symfony\Component\HttpKernel\KernelEvents;
+use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
+use Symfony\Component\HttpKernel\Tests\Logger;
+
+/**
+ * @author Robert Schönthal
+ *
+ * @group time-sensitive
+ */
+class ErrorListenerTest extends TestCase
+{
+ public function testConstruct()
+ {
+ $logger = new TestLogger();
+ $l = new ErrorListener('foo', $logger);
+
+ $_logger = new \ReflectionProperty(\get_class($l), 'logger');
+ $_logger->setAccessible(true);
+ $_controller = new \ReflectionProperty(\get_class($l), 'controller');
+ $_controller->setAccessible(true);
+
+ $this->assertSame($logger, $_logger->getValue($l));
+ $this->assertSame('foo', $_controller->getValue($l));
+ }
+
+ /**
+ * @dataProvider provider
+ */
+ public function testHandleWithoutLogger($event, $event2)
+ {
+ $this->iniSet('error_log', file_exists('/dev/null') ? '/dev/null' : 'nul');
+
+ $l = new ErrorListener('foo');
+ $l->logKernelException($event);
+ $l->onKernelException($event);
+
+ $this->assertEquals(new Response('foo'), $event->getResponse());
+
+ try {
+ $l->logKernelException($event2);
+ $l->onKernelException($event2);
+ $this->fail('RuntimeException expected');
+ } catch (\RuntimeException $e) {
+ $this->assertSame('bar', $e->getMessage());
+ $this->assertSame('foo', $e->getPrevious()->getMessage());
+ }
+ }
+
+ /**
+ * @dataProvider provider
+ */
+ public function testHandleWithLogger($event, $event2)
+ {
+ $logger = new TestLogger();
+
+ $l = new ErrorListener('foo', $logger);
+ $l->logKernelException($event);
+ $l->onKernelException($event);
+
+ $this->assertEquals(new Response('foo'), $event->getResponse());
+
+ try {
+ $l->logKernelException($event2);
+ $l->onKernelException($event2);
+ $this->fail('RuntimeException expected');
+ } catch (\RuntimeException $e) {
+ $this->assertSame('bar', $e->getMessage());
+ $this->assertSame('foo', $e->getPrevious()->getMessage());
+ }
+
+ $this->assertEquals(3, $logger->countErrors());
+ $this->assertCount(3, $logger->getLogs('critical'));
+ }
+
+ public function provider()
+ {
+ if (!class_exists('Symfony\Component\HttpFoundation\Request')) {
+ return [[null, null]];
+ }
+
+ $request = new Request();
+ $exception = new \Exception('foo');
+ $event = new ExceptionEvent(new TestKernel(), $request, HttpKernelInterface::MASTER_REQUEST, $exception);
+ $event2 = new ExceptionEvent(new TestKernelThatThrowsException(), $request, HttpKernelInterface::MASTER_REQUEST, $exception);
+
+ return [
+ [$event, $event2],
+ ];
+ }
+
+ public function testSubRequestFormat()
+ {
+ $listener = new ErrorListener('foo', $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock());
+
+ $kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
+ $kernel->expects($this->once())->method('handle')->willReturnCallback(function (Request $request) {
+ return new Response($request->getRequestFormat());
+ });
+
+ $request = Request::create('/');
+ $request->setRequestFormat('xml');
+
+ $event = new ExceptionEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST, new \Exception('foo'));
+ $listener->onKernelException($event);
+
+ $response = $event->getResponse();
+ $this->assertEquals('xml', $response->getContent());
+ }
+
+ public function testCSPHeaderIsRemoved()
+ {
+ $dispatcher = new EventDispatcher();
+ $kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
+ $kernel->expects($this->once())->method('handle')->willReturnCallback(function (Request $request) {
+ return new Response($request->getRequestFormat());
+ });
+
+ $listener = new ErrorListener('foo', $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(), true);
+
+ $dispatcher->addSubscriber($listener);
+
+ $request = Request::create('/');
+ $event = new ExceptionEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST, new \Exception('foo'));
+ $dispatcher->dispatch($event, KernelEvents::EXCEPTION);
+
+ $response = new Response('', 200, ['content-security-policy' => "style-src 'self'"]);
+ $this->assertTrue($response->headers->has('content-security-policy'));
+
+ $event = new ResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST, $response);
+ $dispatcher->dispatch($event, KernelEvents::RESPONSE);
+
+ $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');
+ }
+}
+
+class TestLogger extends Logger implements DebugLoggerInterface
+{
+ public function countErrors(Request $request = null): int
+ {
+ return \count($this->logs['critical']);
+ }
+}
+
+class TestKernel implements HttpKernelInterface
+{
+ public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true): Response
+ {
+ return new Response('foo');
+ }
+}
+
+class TestKernelThatThrowsException implements HttpKernelInterface
+{
+ public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true): Response
+ {
+ throw new \RuntimeException('bar');
+ }
+}
diff --git a/src/Symfony/Component/HttpKernel/Tests/EventListener/ExceptionListenerTest.php b/src/Symfony/Component/HttpKernel/Tests/EventListener/ExceptionListenerTest.php
index 38966edf2ccbb..28113c14afaba 100644
--- a/src/Symfony/Component/HttpKernel/Tests/EventListener/ExceptionListenerTest.php
+++ b/src/Symfony/Component/HttpKernel/Tests/EventListener/ExceptionListenerTest.php
@@ -20,8 +20,6 @@
use Symfony\Component\HttpKernel\EventListener\ExceptionListener;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\KernelEvents;
-use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
-use Symfony\Component\HttpKernel\Tests\Logger;
/**
* ExceptionListenerTest.
@@ -29,6 +27,7 @@
* @author Robert Schönthal
*
* @group time-sensitive
+ * @group legacy
*/
class ExceptionListenerTest extends TestCase
{
@@ -157,26 +156,4 @@ public function testCSPHeaderIsRemoved()
}
}
-class TestLogger extends Logger implements DebugLoggerInterface
-{
- public function countErrors(Request $request = null): int
- {
- return \count($this->logs['critical']);
- }
-}
-
-class TestKernel implements HttpKernelInterface
-{
- public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true): Response
- {
- return new Response('foo');
- }
-}
-
-class TestKernelThatThrowsException implements HttpKernelInterface
-{
- public function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true): Response
- {
- throw new \RuntimeException('bar');
- }
-}
+class_exists(ErrorListenerTest::class);
diff --git a/src/Symfony/Component/HttpKernel/Tests/EventListener/RouterListenerTest.php b/src/Symfony/Component/HttpKernel/Tests/EventListener/RouterListenerTest.php
index ea88d4b34fa31..2c1e7721b4fa1 100644
--- a/src/Symfony/Component/HttpKernel/Tests/EventListener/RouterListenerTest.php
+++ b/src/Symfony/Component/HttpKernel/Tests/EventListener/RouterListenerTest.php
@@ -19,7 +19,7 @@
use Symfony\Component\HttpKernel\Controller\ArgumentResolver;
use Symfony\Component\HttpKernel\Controller\ControllerResolver;
use Symfony\Component\HttpKernel\Event\RequestEvent;
-use Symfony\Component\HttpKernel\EventListener\ExceptionListener;
+use Symfony\Component\HttpKernel\EventListener\ErrorListener;
use Symfony\Component\HttpKernel\EventListener\RouterListener;
use Symfony\Component\HttpKernel\EventListener\ValidateRequestListener;
use Symfony\Component\HttpKernel\HttpKernel;
@@ -168,7 +168,7 @@ public function testWithBadRequest()
$dispatcher = new EventDispatcher();
$dispatcher->addSubscriber(new ValidateRequestListener());
$dispatcher->addSubscriber(new RouterListener($requestMatcher, $requestStack, new RequestContext()));
- $dispatcher->addSubscriber(new ExceptionListener(function () {
+ $dispatcher->addSubscriber(new ErrorListener(function () {
return new Response('Exception handled', 400);
}));
diff --git a/src/Symfony/Component/HttpKernel/Tests/HttpKernelTest.php b/src/Symfony/Component/HttpKernel/Tests/HttpKernelTest.php
index 9a6170c086d35..14a84b6752e34 100644
--- a/src/Symfony/Component/HttpKernel/Tests/HttpKernelTest.php
+++ b/src/Symfony/Component/HttpKernel/Tests/HttpKernelTest.php
@@ -49,7 +49,7 @@ public function testHandleWhenControllerThrowsAnExceptionAndCatchIsTrueWithAHand
{
$dispatcher = new EventDispatcher();
$dispatcher->addListener(KernelEvents::EXCEPTION, function ($event) {
- $event->setResponse(new Response($event->getException()->getMessage()));
+ $event->setResponse(new Response($event->getThrowable()->getMessage()));
});
$kernel = $this->getHttpKernel($dispatcher, function () { throw new \RuntimeException('foo'); });
@@ -96,7 +96,7 @@ public function testHandleHttpException()
{
$dispatcher = new EventDispatcher();
$dispatcher->addListener(KernelEvents::EXCEPTION, function ($event) {
- $event->setResponse(new Response($event->getException()->getMessage()));
+ $event->setResponse(new Response($event->getThrowable()->getMessage()));
});
$kernel = $this->getHttpKernel($dispatcher, function () { throw new MethodNotAllowedHttpException(['POST']); });
diff --git a/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php b/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php
index 549543e3efb17..2f97c7e04cc66 100644
--- a/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php
+++ b/src/Symfony/Component/Security/Http/Firewall/ExceptionListener.php
@@ -90,7 +90,7 @@ public function unregister(EventDispatcherInterface $dispatcher)
*/
public function onKernelException(GetResponseForExceptionEvent $event)
{
- $exception = $event->getException();
+ $exception = $event->getThrowable();
do {
if ($exception instanceof AuthenticationException) {
$this->handleAuthenticationException($event, $exception);
@@ -128,13 +128,13 @@ private function handleAuthenticationException(GetResponseForExceptionEvent $eve
$event->setResponse($this->startAuthentication($event->getRequest(), $exception));
$event->allowCustomResponseCode();
} catch (\Exception $e) {
- $event->setException($e);
+ $event->setThrowable($e);
}
}
private function handleAccessDeniedException(GetResponseForExceptionEvent $event, AccessDeniedException $exception)
{
- $event->setException(new AccessDeniedHttpException($exception->getMessage(), $exception));
+ $event->setThrowable(new AccessDeniedHttpException($exception->getMessage(), $exception));
$token = $this->tokenStorage->getToken();
if (!$this->authenticationTrustResolver->isFullFledged($token)) {
@@ -148,7 +148,7 @@ private function handleAccessDeniedException(GetResponseForExceptionEvent $event
$event->setResponse($this->startAuthentication($event->getRequest(), $insufficientAuthenticationException));
} catch (\Exception $e) {
- $event->setException($e);
+ $event->setThrowable($e);
}
return;
@@ -177,7 +177,7 @@ private function handleAccessDeniedException(GetResponseForExceptionEvent $event
$this->logger->error('An exception was thrown when handling an AccessDeniedException.', ['exception' => $e]);
}
- $event->setException(new \RuntimeException('Exception thrown when handling an exception.', 0, $e));
+ $event->setThrowable(new \RuntimeException('Exception thrown when handling an exception.', 0, $e));
}
}
diff --git a/src/Symfony/Component/Security/Http/Tests/Firewall/ExceptionListenerTest.php b/src/Symfony/Component/Security/Http/Tests/Firewall/ExceptionListenerTest.php
index f02a52894df1c..fb1db914286fb 100644
--- a/src/Symfony/Component/Security/Http/Tests/Firewall/ExceptionListenerTest.php
+++ b/src/Symfony/Component/Security/Http/Tests/Firewall/ExceptionListenerTest.php
@@ -15,7 +15,6 @@
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
-use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Security\Core\Authentication\AuthenticationTrustResolverInterface;
@@ -40,7 +39,7 @@ public function testAuthenticationExceptionWithoutEntryPoint(\Exception $excepti
$listener->onKernelException($event);
$this->assertNull($event->getResponse());
- $this->assertEquals($eventException, $event->getException());
+ $this->assertEquals($eventException, $event->getThrowable());
}
/**
@@ -59,7 +58,7 @@ public function testAuthenticationExceptionWithEntryPoint(\Exception $exception)
$this->assertEquals('Forbidden', $event->getResponse()->getContent());
$this->assertEquals(403, $event->getResponse()->getStatusCode());
- $this->assertSame($exception, $event->getException());
+ $this->assertSame($exception, $event->getThrowable());
}
public function getAuthenticationExceptionProvider()
@@ -86,8 +85,8 @@ public function testExceptionWhenEntryPointReturnsBadValue()
$listener = $this->createExceptionListener(null, null, null, $entryPoint);
$listener->onKernelException($event);
// the exception has been replaced by our LogicException
- $this->assertInstanceOf('LogicException', $event->getException());
- $this->assertStringEndsWith('start() method must return a Response object (string returned)', $event->getException()->getMessage());
+ $this->assertInstanceOf('LogicException', $event->getThrowable());
+ $this->assertStringEndsWith('start() method must return a Response object (string returned)', $event->getThrowable()->getMessage());
}
/**
@@ -101,7 +100,7 @@ public function testAccessDeniedExceptionFullFledgedAndWithoutAccessDeniedHandle
$listener->onKernelException($event);
$this->assertNull($event->getResponse());
- $this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious());
+ $this->assertSame(null === $eventException ? $exception : $eventException, $event->getThrowable()->getPrevious());
}
/**
@@ -124,7 +123,7 @@ public function testAccessDeniedExceptionFullFledgedAndWithoutAccessDeniedHandle
$this->assertEquals('Unauthorized', $event->getResponse()->getContent());
$this->assertEquals(401, $event->getResponse()->getStatusCode());
- $this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious());
+ $this->assertSame(null === $eventException ? $exception : $eventException, $event->getThrowable()->getPrevious());
}
/**
@@ -141,7 +140,7 @@ public function testAccessDeniedExceptionFullFledgedAndWithAccessDeniedHandlerAn
$listener->onKernelException($event);
$this->assertEquals('error', $event->getResponse()->getContent());
- $this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious());
+ $this->assertSame(null === $eventException ? $exception : $eventException, $event->getThrowable()->getPrevious());
}
/**
@@ -158,7 +157,7 @@ public function testAccessDeniedExceptionNotFullFledged(\Exception $exception, \
$listener->onKernelException($event);
$this->assertEquals('OK', $event->getResponse()->getContent());
- $this->assertSame(null === $eventException ? $exception : $eventException, $event->getException()->getPrevious());
+ $this->assertSame(null === $eventException ? $exception : $eventException, $event->getThrowable()->getPrevious());
}
public function getAccessDeniedExceptionProvider()
@@ -194,11 +193,7 @@ private function createEvent(\Exception $exception, $kernel = null)
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
}
- if (class_exists(ExceptionEvent::class)) {
- return new ExceptionEvent($kernel, Request::create('/'), HttpKernelInterface::MASTER_REQUEST, $exception);
- }
-
- return new GetResponseForExceptionEvent($kernel, Request::create('/'), HttpKernelInterface::MASTER_REQUEST, $exception);
+ return new ExceptionEvent($kernel, Request::create('/'), HttpKernelInterface::MASTER_REQUEST, $exception);
}
private function createExceptionListener(TokenStorageInterface $tokenStorage = null, AuthenticationTrustResolverInterface $trustResolver = null, HttpUtils $httpUtils = null, AuthenticationEntryPointInterface $authenticationEntryPoint = null, $errorPage = null, AccessDeniedHandlerInterface $accessDeniedHandler = null)
diff --git a/src/Symfony/Component/Security/Http/composer.json b/src/Symfony/Component/Security/Http/composer.json
index d51c9d77e438f..686b2b9f1ec54 100644
--- a/src/Symfony/Component/Security/Http/composer.json
+++ b/src/Symfony/Component/Security/Http/composer.json
@@ -19,7 +19,7 @@
"php": "^7.1.3",
"symfony/security-core": "^4.4",
"symfony/http-foundation": "^3.4|^4.0|^5.0",
- "symfony/http-kernel": "^4.3",
+ "symfony/http-kernel": "^4.4",
"symfony/property-access": "^3.4|^4.0|^5.0"
},
"require-dev": {
diff --git a/src/Symfony/Component/Security/composer.json b/src/Symfony/Component/Security/composer.json
index fb5fd768c1265..5251cd8f005fb 100644
--- a/src/Symfony/Component/Security/composer.json
+++ b/src/Symfony/Component/Security/composer.json
@@ -19,7 +19,7 @@
"php": "^7.1.3",
"symfony/event-dispatcher-contracts": "^1.1|^2",
"symfony/http-foundation": "^3.4|^4.0|^5.0",
- "symfony/http-kernel": "^4.3",
+ "symfony/http-kernel": "^4.4",
"symfony/property-access": "^3.4|^4.0|^5.0",
"symfony/service-contracts": "^1.1|^2"
},
pFad - Phonifier reborn
Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy