10000 feature #34309 [HttpKernel] make ExceptionEvent able to propagate any… · symfony/symfony@10a349c · GitHub
[go: up one dir, main page]

Skip to content

Commit 10a349c

Browse files
committed
feature #34309 [HttpKernel] make ExceptionEvent able to propagate any throwable (nicolas-grekas)
This PR was merged into the 4.4 branch. Discussion ---------- [HttpKernel] make ExceptionEvent able to propagate any throwable | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | no | New feature? | no | Deprecations? | yes | Tickets | - | License | MIT | Doc PR | - An alternative to #34306. As a reminder, the goal of this series of PRs is to remove the `FatalThrowableError` wrapper that we introduced to seamlessly handle throwables when they were introduced in PHP 7. From the changelog of `HttpKernel`: * Deprecated methods `ExceptionEvent::get/setException()`, use `get/setThrowable()` instead * Deprecated class `ExceptionListener`, use `ErrorListener` instead And the final target: removed `Symfony\Component\ErrorHandler\Exception\ErrorException` (`FatalThrowableError` is already deprecated.) Commits ------- 6f67f0e [HttpKernel] make ExceptionEvent able to propagate any throwable
2 parents d5ba535 + 6f67f0e commit 10a349c

29 files changed

+393
-150
lines changed

UPGRADE-4.4.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,8 @@ HttpKernel
154154
* Marked the `RouterDataCollector::collect()` method as `@final`.
155155
* The `DataCollectorInterface::collect()` and `Profiler::collect()` methods third parameter signature
156156
will be `\Throwable $exception = null` instead of `\Exception $exception = null` in Symfony 5.0.
157+
* Deprecated methods `ExceptionEvent::get/setException()`, use `get/setThrowable()` instead
158+
* Deprecated class `ExceptionListener`, use `ErrorListener` instead
157159

158160
Lock
159161
----

UPGRADE-5.0.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,8 @@ HttpKernel
290290
* Removed `TranslatorListener` in favor of `LocaleAwareListener`
291291
* The `DebugHandlersListener` class has been made `final`
292292
* Removed `SaveSessionListener` in favor of `AbstractSessionListener`
293+
* Removed methods `ExceptionEvent::get/setException()`, use `get/setThrowable()` instead
294+
* Removed class `ExceptionListener`, use `ErrorListener` instead
293295
* Added new Bundle directory convention consistent with standard skeletons:
294296

295297
```

src/Symfony/Bundle/FrameworkBundle/Console/Application.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
use Symfony\Component\Console\Output\ConsoleOutputInterface;
2020
use Symfony\Component\Console\Output\OutputInterface;
2121
use Symfony\Component\Console\Style\SymfonyStyle;
22+
use Symfony\Component\Debug\Exception\FatalThrowableError;
2223
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
23-
use Symfony\Component\ErrorHandler\Exception\ErrorException;
2424
use Symfony\Component\HttpKernel\Bundle\Bundle;
2525
use Symfony\Component\HttpKernel\Kernel;
2626
use Symfony\Component\HttpKernel\KernelInterface;
@@ -211,7 +211,7 @@ private function renderRegistrationErrors(InputInterface $input, OutputInterface
211211
$this->doRenderThrowable($error, $output);
212212
} else {
213213
if (!$error instanceof \Exception) {
214-
$error = new ErrorException($error);
214+
$error = new FatalThrowableError($error);
215215
}
216216

217217
$this->doRenderException($error, $output);

src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@
9595
<argument type="service" id="error_renderer" />
9696
</service>
9797

98-
<service id="exception_listener" class="Symfony\Component\HttpKernel\EventListener\ExceptionListener">
98+
<service id="exception_listener" class="Symfony\Component\HttpKernel\EventListener\ErrorListener">
9999
<tag name="kernel.event_subscriber" />
100100
<tag name="monolog.logger" channel="request" />
101101
<argument>%kernel.error_controller%</argument>

src/Symfony/Bundle/FrameworkBundle/Tests/Kernel/ConcreteMicroKernel.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
2020
use Symfony\Component\Filesystem\Filesystem;
2121
use Symfony\Component\HttpFoundation\Response;
22-
use Symfony\Component\HttpKernel\Event\RequestEvent;
22+
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
2323
use Symfony\Component\HttpKernel\Kernel;
2424
use Symfony\Component\HttpKernel\KernelEvents;
2525
use Symfony\Component\Routing\RouteCollectionBuilder;
@@ -30,9 +30,9 @@ class ConcreteMicroKernel extends Kernel implements EventSubscriberInterface
3030

3131
private $cacheDir;
3232

33-
public function onKernelException(RequestEvent $event)
33+
public function onKernelException(ExceptionEvent $event)
3434
{
35-
if ($event->getException() instanceof Danger) {
35+
if ($event->getThrowable() instanceof Danger) {
3636
$event->setResponse(Response::create('It\'s dangerous to go alone. Take this ⚔'));
3737
}
3838
}

src/Symfony/Bundle/TwigBundle/Controller/PreviewErrorController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public function previewErrorPageAction(Request $request, $code)
4343

4444
/*
4545
* This Request mimics the parameters set by
46-
* \Symfony\Component\HttpKernel\EventListener\ExceptionListener::duplicateRequest, with
46+
* \Symfony\Component\HttpKernel\EventListener\ErrorListener::duplicateRequest, with
4747
* the additional "showException" flag.
4848
*/
4949

src/Symfony/Component/Console/Application.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,8 @@
4242
use Symfony\Component\Console\Output\OutputInterface;
4343
use Symfony\Component\Console\Style\SymfonyStyle;
4444
use Symfony\Component\Debug\ErrorHandler as LegacyErrorHandler;
45-
use Symfony\Component\Debug\Exception\FatalThrowableError as LegacyFatalThrowableError;
45+
use Symfony\Component\Debug\Exception\FatalThrowableError;
4646
use Symfony\Component\ErrorHandler\ErrorHandler;
47-
use Symfony\Component\ErrorHandler\Exception\ErrorException;
4847
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
4948
use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy;
5049
use Symfony\Contracts\Service\ResetInterface;
@@ -809,7 +808,7 @@ public function renderThrowable(\Throwable $e, OutputInterface $output): void
809808
@trigger_error(sprintf('The "%s::renderException()" method is deprecated since Symfony 4.4, use "renderThrowable()" instead.', __CLASS__), E_USER_DEPRECATED);
810809

811810
if (!$e instanceof \Exception) {
812-
$e = class_exists(ErrorException::class) ? new ErrorException($e) : (class_exists(LegacyFatalThrowableError::class) ? new LegacyFatalThrowableError($e) : new \ErrorException($e->getMessage(), $e->getCode(), E_ERROR, $e->getFile(), $e->getLine()));
811+
$e = class_exists(FatalThrowableError::class) ? new FatalThrowableError($e) : new \ErrorException($e->getMessage(), $e->getCode(), E_ERROR, $e->getFile(), $e->getLine());
813812
}
814813

815814
$this->renderException($e, $output);
@@ -848,7 +847,7 @@ protected function doRenderThrowable(\Throwable $e, OutputInterface $output): vo
848847
@trigger_error(sprintf('The "%s::doRenderException()" method is deprecated since Symfony 4.4, use "doRenderThrowable()" instead.', __CLASS__), E_USER_DEPRECATED);
849848

850849
if (!$e instanceof \Exception) {
851-
$e = class_exists(ErrorException::class) ? new ErrorException($e) : (class_exists(LegacyFatalThrowableError::class) ? new LegacyFatalThrowableError($e) : new \ErrorException($e->getMessage(), $e->getCode(), E_ERROR, $e->getFile(), $e->getLine()));
850+
$e = class_exists(FatalThrowableError::class) ? new FatalThrowableError($e) : new \ErrorException($e->getMessage(), $e->getCode(), E_ERROR, $e->getFile(), $e->getLine());
852851
}
853852

854853
$this->doRenderException($e, $output);

src/Symfony/Component/Debug/Exception/FatalErrorException.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@
1111

1212
namespace Symfony\Component\Debug\Exception;
1313

14-
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', FatalErrorException::class, \Symfony\Component\ErrorHandler\Exception\ErrorException::class), E_USER_DEPRECATED);
14+
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4, use "%s" instead.', FatalErrorException::class, \Symfony\Component\ErrorHandler\Error\FatalError::class), E_USER_DEPRECATED);
1515

1616
/**
1717
* Fatal Error Exception.
1818
*
1919
* @author Konstanton Myakshin <koc-dp@yandex.ru>
2020
*
21-
* @deprecated since Symfony 4.4, use Symfony\Component\ErrorHandler\Exception\ErrorException instead.
21+
* @deprecated since Symfony 4.4, use Symfony\Component\ErrorHandler\Error\FatalError instead.
2222
*/
2323
class FatalErrorException extends \ErrorException
2424
{

src/Symfony/Component/Debug/Exception/FatalThrowableError.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@
1111

1212
namespace Symfony\Component\Debug\Exception;
1313

14-
@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);
14+
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.4.', FatalThrowableError::class), E_USER_DEPRECATED);
1515

1616
/**
1717
* Fatal Throwable Error.
1818
*
1919
* @author Nicolas Grekas <p@tchwork.com>
2020
*
21-
* @deprecated since Symfony 4.4, use Symfony\Component\ErrorHandler\Exception\ErrorException instead.
21+
* @deprecated since Symfony 4.4
2222
*/
2323
class FatalThrowableError extends FatalErrorException
2424
{

src/Symfony/Component/ErrorHandler/Exception/ErrorException.php

Lines changed: 0 additions & 42 deletions
This file was deleted.

src/Symfony/Component/ErrorRenderer/Exception/FlattenException.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
namespace Symfony\Component\ErrorRenderer\Exception;
1313

1414
use Symfony\Component\Debug\Exception\FlattenException as LegacyFlattenException;
15-
use Symfony\Component\ErrorHandler\Exception\ErrorException;
1615
use Symfony\Component\HttpFoundation\Exception\RequestExceptionInterface;
1716
use Symfony\Component\HttpFoundation\Response;
1817
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
@@ -70,7 +69,7 @@ public static function createFromThrowable(\Throwable $exception, int $statusCod
7069
$e->setStatusCode($statusCode);
7170
$e->setHeaders($headers);
7271
$e->setTraceFromThrowable($exception);
73-
$e->setClass($exception instanceof ErrorException ? $exception->getOriginalClassName() : \get_class($exception));
72+
$e->setClass(\get_class($exception));
7473
$e->setFile($exception->getFile());
7574
$e->setLine($exception->getLine());
7675

src/Symfony/Component/ErrorRenderer/Tests/Exception/FlattenExceptionTest.php

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
namespace Symfony\Component\ErrorRenderer\Tests\Exception;
1313

1414
use PHPUnit\Framework\TestCase;
15-
use Symfony\Component\ErrorHandler\Exception\ErrorException;
1615
use Symfony\Component\ErrorRenderer\Exception\FlattenException;
1716
use Symfony\Component\HttpFoundation\Exception\SuspiciousOperationException;
1817
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
@@ -130,16 +129,6 @@ public function testFlattenHttpException(\Throwable $exception)
130129
$this->assertInstanceOf($flattened->getClass(), $exception, 'The class is set to the class of the original exception');
131130
}
132131

133-
public function testWrappedThrowable()
134-
{
135-
$exception = new ErrorException(new \DivisionByZeroError('Ouch', 42));
136-
$flattened = FlattenException::createFromThrowable($exception);
137-
138-
$this->assertSame('Ouch', $flattened->getMessage(), 'The message is copied from the original error.');
139-
$this->assertSame(42, $flattened->getCode(), 'The code is copied from the original error.');
140-
$this->assertSame('DivisionByZeroError', $flattened->getClass(), 'The class is set to the class of the original error');
141-
}
142-
143132
public function testThrowable()
144133
{
145134
$error = new \DivisionByZeroError('Ouch', 42);

src/Symfony/Component/HttpKernel/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ CHANGELOG
2121
* Marked the `RouterDataCollector::collect()` method as `@final`.
2222
* The `DataCollectorInterface::collect()` and `Profiler::collect()` methods third parameter signature
2323
will be `\Throwable $exception = null` instead of `\Exception $exception = null` in Symfony 5.0.
24+
* Deprecated methods `ExceptionEvent::get/setException()`, use `get/setThrowable()` instead
25+
* Deprecated class `ExceptionListener`, use `ErrorListener` instead
2426

2527
4.3.0
2628
-----

src/Symfony/Component/HttpKernel/Controller/ErrorController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public function preview(Request $request, int $code): Response
5252

5353
/*
5454
* This Request mimics the parameters set by
55-
* \Symfony\Component\HttpKernel\EventListener\ExceptionListener::duplicateRequest, with
55+
* \Symfony\Component\HttpKernel\EventListener\ErrorListener::duplicateRequest, with
5656
* the additional "showException" flag.
5757
*/
5858
$subRequest = $request->duplicate(null, null, [

src/Symfony/Component/HttpKernel/Event/GetResponseForExceptionEvent.php

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,45 +19,55 @@
1919
*/
2020
class GetResponseForExceptionEvent extends RequestEvent
2121
{
22-
/**
23-
* The exception object.
24-
*
25-
* @var \Exception
26-
*/
22+
private $throwable;
2723
private $exception;
28-
29-
/**
30-
* @var bool
31-
*/
3224
private $allowCustomResponseCode = false;
3325

34-
public function __construct(HttpKernelInterface $kernel, Request $request, int $requestType, \Exception $e)
26+
public function __construct(HttpKernelInterface $kernel, Request $request, int $requestType, \Throwable $e)
3527
{
3628
parent::__construct($kernel, $request, $requestType);
3729

38-
$this->setException($e);
30+
$this->setThrowable($e);
31+
}
32+
33+
public function getThrowable(): \Throwable
34+
{
35+
return $this->throwable;
36+
}
37+
38+
/**
39+
* Replaces the thrown exception.
40+
*
41+
* This exception will be thrown if no response is set in the event.
42+
*/
43+
public function setThrowable(\Throwable $exception): void
44+
{
45+
$this->exception = null;
46+
$this->throwable = $exception;
3947
}
4048

4149
/**
42-
* Returns the thrown exception.
50+
* @deprecated since Symfony 4.4, use getThrowable instead
4351
*
4452
* @return \Exception The thrown exception
4553
*/
4654
public function getException()
4755
{
48-
return $this->exception;
56+
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.4, use "getThrowable()" instead.', __METHOD__), E_USER_DEPRECATED);
57+
58+
return $this->exception ?? $this->exception = $this->throwable instanceof \Exception ? $this->throwable : new FatalThrowableError($this->throwable);
4959
}
5060

5161
/**
52-
* Replaces the thrown exception.
53-
*
54-
* This exception will be thrown if no response is set in the event.
< F438 div aria-hidden="true" class="position-absolute top-0 d-flex user-select-none DiffLineTableCellParts-module__comment-indicator--eI0hb">
62+
* @deprecated since Symfony 4.4, use setThrowable instead
5563
*
5664
* @param \Exception $exception The thrown exception
5765
*/
5866
public function setException(\Exception $exception)
5967
{
60-
$this->exception = $exception;
68+
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.4, use "setThrowable()" instead.', __METHOD__), E_USER_DEPRECATED);
69+
70+
$this->throwable = $this->exception = $exception;
6171
}
6272

6373
/**

src/Symfony/Component/HttpKernel/EventListener/DebugHandlersListener.php

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
use Symfony\Component\Console\ConsoleEvents;
1616
use Symfony\Component\Console\Event\ConsoleEvent;
1717
use Symfony\Component\Console\Output\ConsoleOutputInterface;
18+
use Symfony\Component\Debug\Exception\FatalThrowableError;
1819
use Symfony\Component\ErrorHandler\ErrorHandler;
19-
use Symfony\Component\ErrorHandler\Exception\ErrorException;
2020
use Symfony\Component\EventDispatcher\Event;
2121
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
2222
use Symfony\Component\HttpKernel\Debug\FileLinkFormatter;
@@ -112,10 +112,6 @@ public function configure(Event $event = null)
112112
throw $e;
113113
}
114114

115-
if (!$e instanceof \Exception) {
116-
$e = new ErrorException($e);
117-
}
118-
119115
$hasRun = true;
120116
$kernel->terminateWithException($e, $request);
121117
};
@@ -130,7 +126,7 @@ public function configure(Event $event = null)
130126
$app->renderThrowable($e, $output);
131127
} else {
132128
if (!$e instanceof \Exception) {
133-
$e = new ErrorException($e);
129+
$e = new FatalThrowableError($e);
134130
}
135131

136132
$app->renderException($e, $output);

0 commit comments

Comments
 (0)
0