Skip to content

Commit 72dd176

Browse files
feature #33065 Deprecate things that prevent \Throwable from bubbling down (fancyweb)
This PR was merged into the 4.4 branch. Discussion ---------- Deprecate things that prevent \Throwable from bubbling down | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | yes (todo update CHANGELOGS & UPGRADES) | Tests pass? | yes | Fixed tickets | #32605 | License | MIT | Doc PR | - ~The goal of this PR is to allow `\Throwable` forwarded from the`ErrorHandler::handleException()` method (cf #33038) to bubble down in our code base without having to convert them into exceptions.~ ~WIP because I'm blocked by 2 things caused by `GetResponseForExceptionEvent::getThrowable()` returning a `\Throwable` instead of an `\Exception`.~ ~1. This `\Throwable` end up in `DataCollectorInterface::collect()` (cf `ProfilerListener`). So that looks impossible to support in 4.4. What can we do?~ ~2. The second blocker is `ExceptionListener::duplicateRequest()`. We are not gonna rename this method to support `\Throwable` I guess. What can we do?~ Since there are blockers to do it in 4.4, let's prepare for the future and deprecate the things that block us. Commits ------- abef506 Deprecate things that prevent \Throwable from bubbling down
2 parents 4cd3dc8 + abef506 commit 72dd176

35 files changed

+158
-21
lines changed

UPGRADE-4.4.md

+20
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,15 @@ Cache
55
-----
66

77
* Added argument `$prefix` to `AdapterInterface::clear()`
8+
* Marked the `CacheDataCollector` class as `@final`.
89

910
Console
1011
-------
1112

1213
* Deprecated finding hidden commands using an abbreviation, use the full name instead
1314
* Deprecated returning `null` from `Command::execute()`, return `0` instead
15+
* Deprecated the `Application::renderException()` and `Application::doRenderException()` methods,
16+
use `renderThrowable()` and `doRenderThrowable()` instead.
1417

1518
Debug
1619
-----
@@ -65,6 +68,7 @@ DoctrineBridge
6568
* Deprecated `RegistryInterface`, use `Doctrine\Common\Persistence\ManagerRegistry`.
6669
* Added a new `getMetadataDriverClass` method to replace class parameters in `AbstractDoctrineExtension`. This method
6770
will be abstract in Symfony 5 and must be declared in extending classes.
71+
* Marked the `DoctrineDataCollector` class as `@final`.
6872

6973
Filesystem
7074
----------
@@ -91,6 +95,7 @@ FrameworkBundle
9195
* Deprecated `routing.loader.service`, use `routing.loader.container` instead.
9296
* Not tagging service route loaders with `routing.route_loader` has been deprecated.
9397
* Overriding the methods `KernelTestCase::tearDown()` and `WebTestCase::tearDown()` without the `void` return-type is deprecated.
98+
* Marked the `RouterDataCollector` class as `@final`.
9499

95100
HttpClient
96101
----------
@@ -144,6 +149,12 @@ HttpKernel
144149
current directory or with a glob pattern. The fallback directories have never been advocated
145150
so you likely do not use those in any app based on the SF Standard or Flex edition.
146151
* Getting the container from a non-booted kernel is deprecated
152+
* Marked the `AjaxDataCollector`, `ConfigDataCollector`, `EventDataCollector`,
153+
`ExceptionDataCollector`, `LoggerDataCollector`, `MemoryDataCollector`,
154+
`RequestDataCollector` and `TimeDataCollector` classes as `@final`.
155+
* Marked the `RouterDataCollector::collect()` method as `@final`.
156+
* The `DataCollectorInterface::collect()` and `Profiler::collect()` methods third parameter signature
157+
will be `\Throwable $exception = null` instead of `\Exception $exception = null` in Symfony 5.0.
147158

148159
Lock
149160
----
@@ -164,6 +175,7 @@ Messenger
164175
* [BC BREAK] Removed `$retryStrategyLocator` argument from `ConsumeMessagesCommand::__construct`.
165176
* [BC BREAK] Removed `$senderClassOrAlias` argument from `RedeliveryStamp::__construct`.
166177
* [BC BREAK] Removed `UnknownSenderException`.
178+
* Marked the `MessengerDataCollector` class as `@final`.
167179

168180
Mime
169181
----
@@ -216,6 +228,11 @@ Security
216228
) {}
217229
```
218230

231+
SecurityBundle
232+
--------------
233+
234+
* Marked the `SecurityDataCollector` class as `@final`.
235+
219236
Serializer
220237
----------
221238

@@ -231,13 +248,15 @@ Translation
231248

232249
* Deprecated support for using `null` as the locale in `Translator`.
233250
* Deprecated accepting STDIN implicitly when using the `lint:xliff` command, use `lint:xliff -` (append a dash) instead to make it explicit.
251+
* Marked the `TranslationDataCollector` class as `@final`.
234252

235253
TwigBridge
236254
----------
237255

238256
* Deprecated to pass `$rootDir` and `$fileLinkFormatter` as 5th and 6th argument respectively to the
239257
`DebugCommand::__construct()` method, swap the variables position.
240258
* Deprecated accepting STDIN implicitly when using the `lint:twig` command, use `lint:twig -` (append a dash) instead to make it explicit.
259+
* Marked the `TwigDataCollector` class as `@final`.
241260

242261
TwigBundle
243262
----------
@@ -342,6 +361,7 @@ Validator
342361
* deprecated `ValidatorBuilder::setMetadataCache`, use `ValidatorBuilder::setMappingCache` instead.
343362
* The `Range` constraint has a new message option `notInRangeMessage` that is used when both `min` and `max` values are set.
344363
In case you are using custom translations make sure to add one for this new message.
364+
* Marked the `ValidatorDataCollector` class as `@final`.
345365

346366
WebProfilerBundle
347367
-----------------

src/Symfony/Bridge/Doctrine/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ CHANGELOG
88
* deprecated `RegistryInterface`, use `Doctrine\Common\Persistence\ManagerRegistry`
99
* added support for invokable event listeners
1010
* added `getMetadataDriverClass` method to deprecate class parameters in service configuration files
11+
* Marked the `DoctrineDataCollector` class as `@final`.
1112

1213
4.3.0
1314
-----

src/Symfony/Bridge/Doctrine/DataCollector/DoctrineDataCollector.php

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
* DoctrineDataCollector.
2424
*
2525
* @author Fabien Potencier <fabien@symfony.com>
26+
*
27+
* @final since Symfony 4.4
2628
*/
2729
class DoctrineDataCollector extends DataCollector
2830
{

src/Symfony/Bridge/Twig/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ CHANGELOG
1111
* deprecated accepting STDIN implicitly when using the `lint:twig` command, use `lint:twig -` (append a dash) instead to make it explicit.
1212
* added `--show-deprecations` option to the `lint:twig` command
1313
* added support for Bootstrap4 switches, use `switch-custom` as `label_attr` in a `CheckboxType`
14+
* Marked the `TwigDataCollector` class as `@final`.
1415

1516
4.3.0
1617
-----

src/Symfony/Bridge/Twig/DataCollector/TwigDataCollector.php

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
* TwigDataCollector.
2626
*
2727
* @author Fabien Potencier <fabien@symfony.com>
28+
*
29+
* @final since Symfony 4.4
2830
*/
2931
class TwigDataCollector extends DataCollector implements LateDataCollectorInterface
3032
{

src/Symfony/Bundle/FrameworkBundle/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ CHANGELOG
2020
* [BC Break] The `framework.messenger.routing.senders` config key is not deep merged anymore.
2121
* Added `secrets:*` commands and `%env(secret:...)%` processor to deal with secrets seamlessly.
2222
* Made `framework.session.handler_id` accept a DSN
23+
* Marked the `RouterDataCollector` class as `@final`.
2324

2425
4.3.0
2526
-----

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

+8-4
Original file line numberDiff line numberDiff line change
@@ -207,11 +207,15 @@ private function renderRegistrationErrors(InputInterface $input, OutputInterface
207207
(new SymfonyStyle($input, $output))->warning('Some commands could not be registered:');
208208

209209
foreach ($this->registrationErrors as $error) {
210-
if (!$error instanceof \Exception) {
211-
$error = new ErrorException($error);
212-
}
210+
if (method_exists($this, 'doRenderThrowable')) {
211+
$this->doRenderThrowable($error, $output);
212+
} else {
213+
if (!$error instanceof \Exception) {
214+
$error = new ErrorException($error);
215+
}
213216

214-
$this->doRenderException($error, $output);
217+
$this->doRenderException($error, $output);
218+
}
215219
}
216220
}
217221
}

src/Symfony/Bundle/FrameworkBundle/DataCollector/RouterDataCollector.php

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
* RouterDataCollector.
2020
*
2121
* @author Fabien Potencier <fabien@symfony.com>
22+
*
23+
* @final since Symfony 4.4
2224
*/
2325
class RouterDataCollector extends BaseRouterDataCollector
2426
{

src/Symfony/Bundle/SecurityBundle/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ CHANGELOG
66

77
* Added new `argon2id` encoder, undeprecated the `bcrypt` and `argon2i` ones (using `auto` is still recommended by default.)
88
* Deprecated the usage of "query_string" without a "search_dn" and a "search_password" config key in Ldap factories.
9+
* Marked the `SecurityDataCollector` class as `@final`.
910

1011
4.3.0
1112
-----

src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php

+2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434

3535
/**
3636
* @author Fabien Potencier <fabien@symfony.com>
37+
*
38+
* @final since Symfony 4.4
3739
*/
3840
class SecurityDataCollector extends DataCollector implements LateDataCollectorInterface
3941
{

src/Symfony/Component/Cache/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ CHANGELOG
1111
* added `DeflateMarshaller` to compress serialized values
1212
* removed support for phpredis 4 `compression`
1313
* [BC BREAK] `RedisTagAwareAdapter` is not compatible with `RedisCluster` from `Predis` anymore, use `phpredis` instead
14+
* Marked the `CacheDataCollector` class as `@final`.
1415

1516
4.3.0
1617
-----

src/Symfony/Component/Cache/DataCollector/CacheDataCollector.php

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
/**
2222
* @author Aaron Scherer <aequasi@gmail.com>
2323
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
24+
*
25+
* @final since Symfony 4.4
2426
*/
2527
class CacheDataCollector extends DataCollector implements LateDataCollectorInterface
2628
{

src/Symfony/Component/Console/Application.php

+59-5
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,10 @@ public function run(InputInterface $input = null, OutputInterface $output = null
128128
}
129129

130130
$renderException = function (\Throwable $e) use ($output) {
131-
if (!$e instanceof \Exception) {
132-
$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()));
133-
}
134131
if ($output instanceof ConsoleOutputInterface) {
135-
$this->renderException($e, $output->getErrorOutput());
132+
$this->renderThrowable($e, $output->getErrorOutput());
136133
} else {
137-
$this->renderException($e, $output);
134+
$this->renderThrowable($e, $output);
138135
}
139136
};
140137
if ($phpHandler = set_exception_handler($renderException)) {
@@ -792,20 +789,77 @@ public static function getAbbreviations($names)
792789

793790
/**
794791
* Renders a caught exception.
792+
*
793+
* @deprecated since Symfony 4.4, use "renderThrowable()" instead
795794
*/
796795
public function renderException(\Exception $e, OutputInterface $output)
797796
{
797+
@trigger_error(sprintf('The "%s::renderException()" method is deprecated since Symfony 4.4, use "renderThrowable()" instead.', __CLASS__), E_USER_DEPRECATED);
798+
798799
$output->writeln('', OutputInterface::VERBOSITY_QUIET);
799800

800801
$this->doRenderException($e, $output);
801802

803+
$this->finishRenderThrowableOrException($output);
804+
}
805+
806+
public function renderThrowable(\Throwable $e, OutputInterface $output): void
807+
{
808+
if (__CLASS__ !== \get_class($this) && __CLASS__ === (new \ReflectionMethod($this, 'renderThrowable'))->getDeclaringClass()->getName() && __CLASS__ !== (new \ReflectionMethod($this, 'renderException'))->getDeclaringClass()->getName()) {
809+
@trigger_error(sprintf('The "%s::renderException()" method is deprecated since Symfony 4.4, use "renderThrowable()" instead.', __CLASS__), E_USER_DEPRECATED);
810+
811+
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()));
813+
}
814+
815+
$this->renderException($e, $output);
816+
817+
return;
818+
}
819+
820+
$output->writeln('', OutputInterface::VERBOSITY_QUIET);
821+
822+
$this->doRenderThrowable($e, $output);
823+
824+
$this->finishRenderThrowableOrException($output);
825+
}
826+
827+
private function finishRenderThrowableOrException(OutputInterface $output): void
828+
{
802829
if (null !== $this->runningCommand) {
803830
$output->writeln(sprintf('<info>%s</info>', sprintf($this->runningCommand->getSynopsis(), $this->getName())), OutputInterface::VERBOSITY_QUIET);
804831
$output->writeln('', OutputInterface::VERBOSITY_QUIET);
805832
}
806833
}
807834

835+
/**
836+
* @deprecated since Symfony 4.4, use "doRenderThrowable()" instead
837+
*/
808838
protected function doRenderException(\Exception $e, OutputInterface $output)
839+
{
840+
@trigger_error(sprintf('The "%s::doRenderException()" method is deprecated since Symfony 4.4, use "doRenderThrowable()" instead.', __CLASS__), E_USER_DEPRECATED);
841+
842+
$this->doActuallyRenderThrowable($e, $output);
843+
}
844+
845+
protected function doRenderThrowable(\Throwable $e, OutputInterface $output): void
846+
{
847+
if (__CLASS__ !== \get_class($this) && __CLASS__ === (new \ReflectionMethod($this, 'doRenderThrowable'))->getDeclaringClass()->getName() && __CLASS__ !== (new \ReflectionMethod($this, 'doRenderException'))->getDeclaringClass()->getName()) {
848+
@trigger_error(sprintf('The "%s::doRenderException()" method is deprecated since Symfony 4.4, use "doRenderThrowable()" instead.', __CLASS__), E_USER_DEPRECATED);
849+
850+
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()));
852+
}
853+
854+
$this->doRenderException($e, $output);
855+
856+
return;
857+
}
858+
859+
$this->doActuallyRenderThrowable($e, $output);
860+
}
861+
862+
private function doActuallyRenderThrowable(\Throwable $e, OutputInterface $output): void
809863
{
810864
do {
811865
$message = trim($e->getMessage());

src/Symfony/Component/Console/CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ CHANGELOG
1111
* marked all dispatched event classes as `@final`
1212
* added support for displaying table horizontally
1313
* deprecated returning `null` from `Command::execute()`, return `0` instead
14+
* Deprecated the `Application::renderException()` and `Application::doRenderException()` methods,
15+
use `renderThrowable()` and `doRenderThrowable()` instead.
1416

1517
4.3.0
1618
-----

src/Symfony/Component/HttpKernel/CHANGELOG.md

+6
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ CHANGELOG
1515
* Marked all dispatched event classes as `@final`
1616
* Added `ErrorController` to enable the preview and error rendering mechanism
1717
* Getting the container from a non-booted kernel is deprecated.
18+
* Marked the `AjaxDataCollector`, `ConfigDataCollector`, `EventDataCollector`,
19+
`ExceptionDataCollector`, `LoggerDataCollector`, `MemoryDataCollector`,
20+
`RequestDataCollector` and `TimeDataCollector` classes as `@final`.
21+
* Marked the `RouterDataCollector::collect()` method as `@final`.
22+
* The `DataCollectorInterface::collect()` and `Profiler::collect()` methods third parameter signature
23+
will be `\Throwable $exception = null` instead of `\Exception $exception = null` in Symfony 5.0.
1824

1925
4.3.0
2026
-----

src/Symfony/Component/HttpKernel/DataCollector/AjaxDataCollector.php

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
* AjaxDataCollector.
1919
*
2020
* @author Bart van den Burg <bart@burgov.nl>
21+
*
22+
* @final since Symfony 4.4
2123
*/
2224
class AjaxDataCollector extends DataCollector
2325
{

src/Symfony/Component/HttpKernel/DataCollector/ConfigDataCollector.php

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
/**
2121
* @author Fabien Potencier <fabien@symfony.com>
22+
*
23+
* @final since Symfony 4.4
2224
*/
2325
class ConfigDataCollector extends DataCollector implements LateDataCollectorInterface
2426
{

src/Symfony/Component/HttpKernel/DataCollector/EventDataCollector.php

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
* EventDataCollector.
2424
*
2525
* @author Fabien Potencier <fabien@symfony.com>
26+
*
27+
* @final since Symfony 4.4
2628
*/
2729
class EventDataCollector extends DataCollector implements LateDataCollectorInterface
2830
{

src/Symfony/Component/HttpKernel/DataCollector/ExceptionDataCollector.php

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
* ExceptionDataCollector.
2020
*
2121
* @author Fabien Potencier <fabien@symfony.com>
22+
*
23+
* @final since Symfony 4.4
2224
*/
2325
class ExceptionDataCollector extends DataCollector
2426
{

src/Symfony/Component/HttpKernel/DataCollector/LoggerDataCollector.php

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
* LogDataCollector.
2222
*
2323
* @author Fabien Potencier <fabien@symfony.com>
24+
*
25+
* @final since Symfony 4.4
2426
*/
2527
class LoggerDataCollector extends DataCollector implements LateDataCollectorInterface
2628
{

src/Symfony/Component/HttpKernel/DataCollector/MemoryDataCollector.php

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
* MemoryDataCollector.
1919
*
2020
* @author Fabien Potencier <fabien@symfony.com>
21+
*
22+
* @final since Symfony 4.4
2123
*/
2224
class MemoryDataCollector extends DataCollector implements LateDataCollectorInterface
2325
{

src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php

+2
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222

2323
/**
2424
* @author Fabien Potencier <fabien@symfony.com>
25+
*
26+
* @final since Symfony 4.4
2527
*/
2628
class RequestDataCollector extends DataCollector implements EventSubscriberInterface, LateDataCollectorInterface
2729
{

src/Symfony/Component/HttpKernel/DataCollector/RouterDataCollector.php

+2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ public function __construct()
3333

3434
/**
3535
* {@inheritdoc}
36+
*
37+
* @final since Symfony 4.4
3638
*/
3739
public function collect(Request $request, Response $response, \Exception $exception = null)
3840
{

src/Symfony/Component/HttpKernel/DataCollector/TimeDataCollector.php

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
/**
2121
* @author Fabien Potencier <fabien@symfony.com>
22+
*
23+
* @final since Symfony 4.4
2224
*/
2325
class TimeDataCollector extends DataCollector implements LateDataCollectorInterface
2426
{

0 commit comments

Comments
 (0)