-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[FrameworkBundle][HttpKernel] Add deprecation warning to show HttpKernel::handle()
will catch throwables
#45997
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
A deprecation for which there is no way to opt-in for the new behavior is bad: it does not help migrating and will annoy people seeing it without being able to get rid of it. |
Hm. You are very correct. Thank you. Do you have a suggestion on how to make an opt-in? |
Well, you would need some kind of configuration parameter that can turn on the catching of errors. |
Thank you for the review. I've update the PR with a way to opt-in to the new behaviour. I've also added some tests. |
f806125
to
e414827
Compare
Psalm and Fabbot are both false negatives. It seams like the 8.2 test fails for unrelated reasons. PHPUnit 8.1 low-deps fails because of this PR. Any suggestions how I could fix them? |
Thank you very much for bringing this topic up again. I like how you allow to opt-in to the new behavior.
The lazy fix would be to add conflict rules to the composer.json files of SecurityBundle and WebProfilerBundle, for FrameworkBundle < 6.1. The alterantive would be to make the test setup for the bundles more complex by setting/removing that option conditionally and I'm not sure that's worth it. |
Thank you for the feedback. I've updated the PR. |
67077c1
to
08ce868
Compare
The PR is rebased and updated. status: Waiting for review |
77bb69f
to
a5acdbb
Compare
The PR is updated for 6.2. Fabbot is a false negative and the PHP 8.2 test fail is unrelated. I would be happy to get another review on this. I believe it is ready to merge |
Thank you for the review. I've applied the changes. |
src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
Outdated
Show resolved
Hide resolved
public static function getExceptions(): array | ||
{ | ||
$exceptions = self::$exceptions; | ||
self::$exceptions = []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For a getter method I would not expect the method to modify the object's state but to be able to call the method several times with the same result.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll name this resetExceptions()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now it's not really clear that I could use this method retrieve the list of all caught exceptions. What about adapting the schema used for methods in the SPL and use something like shiftAll()
?
src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Uid/config_disabled.yml
Outdated
Show resolved
Hide resolved
src/Symfony/Bundle/FrameworkBundle/Tests/Functional/UidTest.php
Outdated
Show resolved
Hide resolved
I've applied all changes and the CI is green |
98e1a72
to
a906e6c
Compare
I've applied the suggested changes. I've rebased the PR and the tests are green. Could I get a final round of reviews? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would seem the composer.json
file of the WebProfilerBundle
needs an update as well (https://github.com/symfony/symfony/blob/6.2/src/Symfony/Bundle/WebProfilerBundle/composer.json#L21).
EDIT: it seems I've missed https://github.com/symfony/symfony/pull/45997/files#diff-b7944e9265a9fd4f68f0fb505d9c8375791e607b9709dd3bd93519990683f4c7R62
{ | ||
$this->dispatcher = $dispatcher; | ||
$this->resolver = $resolver; | ||
$this->requestStack = $requestStack ?? new RequestStack(); | ||
$this->argumentResolver = $argumentResolver ?? new ArgumentResolver(); | ||
$this->catchThrowable = $catchThrowable; | ||
if (!$catchThrowable) { | ||
trigger_deprecation('symfony/http-kernel', '6.2', 'Starting from 7.0, "%s::handle()" will catch \Throwable exceptions and convert them to HttpFoundation responses.', self::class); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This depreciation message is not actionable. It should tell to pass true
as last argument to get rid of it.
Although this would still not be the right fix in the framework context, since the catch_all_throwables
option needs to be set to true
.
Maybe the configuration needs a ->validate()
node to trigger on false
with the "good" message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated the exception message.
Maybe the configuration needs a ->validate() node to trigger on false with the "good" message.
Hm.. Yeah. But isn't that overkill?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can see two paths. Once you get rid of the deprecation you should be ready for 7.0, but in this case it means passing true
instead of false
.
-
Removing the argument and the config node could be done in 8.0, once first deprecated in 7.1.
-
However removing the arg as it seems to be expected in 7.0 won't break, but will make passing the arg some dead code without notice. Also removing the config node in 7.0 would be a BC break if devs continue to define it to
true
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the constructor argument and config is part of the deprecation layer they will both be removed in 7.0.
Aren't we overthinking now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
choices_as_values
option was used for Symfony 2 deprecation layer, but deprecated in 3.1,
logout_on_user_change
option was used in Symfony 3 deprecation layer and deprecated in 4.1 and so on.
The BC should be to not change your code when upgrading to 7.0, in this case changing false
to true
would make it work, but once done, another change would be required to remove config and arg, so they must still exist before we can safely remove them.
In other words, the deprecation layer itself cannot be deprecated in 6.x nor removed in 7.0, it needs to be deprecated in 7.1.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe the configuration needs a ->validate() node to trigger on false with the "good" message.
Hm... Yeah. But isn't that overkill?
Well, the problem I see is that most devs using the framework do not even know there is an HttpKernel
service nor how to change this arg.
However, mentioning the config key in this message from the component feels wrong.
It would be nice to have this default to |
src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
Outdated
Show resolved
Hide resolved
src/Symfony/Bundle/FrameworkBundle/Tests/Functional/app/Uid/config_disabled.yml
Outdated
Show resolved
Hide resolved
HttpKernel::handle()
will catch throwables
96fefac
to
7977a15
Compare
I've rebased the PR and squashed the commits. The CI failures are not related to this PR. Could I ask you to review this PR again to decide if it is good enough to merge. |
Thank you @Nyholm. |
Awesome. Thank you for merging. Big thank you to all reviewers too |
…es` to allow `HttpKernel` to handle thrown `Error` in addition to `Exception` (nicolas-grekas) This PR was squashed before being merged into the 6.2 branch. Discussion ---------- [HttpKernel] Add request attribute `_handle_all_throwables` to allow `HttpKernel` to handle thrown `Error` in addition to `Exception` | Q | A | ------------- | --- | Branch? | 6.2 | Bug fix? | no | New feature? | no | Deprecations? | no | Tickets | - | License | MIT | Doc PR | - I understand the motivation behind #45997 but I don't think the deprecation is worth the migration cost on *all* users of Symfony. The burden of enabling this setting should only be on use cases where getting a response back is needed. The previous behavior was just fine in common situations. /cc `@catch56` for Drupal FYI /cc `@Nyholm` also Commits ------- 8604d3a [HttpKernel] Add request attribute `_handle_all_throwables` to allow `HttpKernel` to handle thrown `Error` in addition to `Exception`
…st to fix CI (jmsche) This PR was merged into the main branch. Discussion ---------- Rename catch_all_throwables to handle_all_throwables in test to fix CI Little fix required to make CI pass again :) The `catch_all_throwables` parameter was renamed by this PR: symfony/symfony#45997 Commits ------- aae2142 Rename catch_all_throwables to handle_all_throwables in test to fix CI
…st to fix CI (jmsche) This PR was merged into the main branch. Discussion ---------- Rename catch_all_throwables to handle_all_throwables in test to fix CI Little fix required to make CI pass again :) The `catch_all_throwables` parameter was renamed by this PR: symfony/symfony#45997 Commits ------- aae2142 Rename catch_all_throwables to handle_all_throwables in test to fix CI
I suggest that starting from Symfony 7.0 the
HttpKernel
will start to catch\Throwable
and convert them to aResponse
.This was first asked in #16205, I face a similar issue with Runtime component and Bref..
The reason I push for this change is to embrace the request/response workflow of the Kernel without trusting the custom error handler. In an environment where you serve multiple requests with the same PHP process (read: RoadRunner, Swoole, Bref) you would write something like:
(pseudo code of course. Here is a real example)
The
exit(1)
means a hard crash. For Bref Runtime it would result in a 500 error from API-gateway. Since the\Throwable
is caught, the Symfony error handler is not used. If we would not to catch the\Throwable
, then the Symfony error handler would be used, but it would print a Response instead of returning it. (Printing a response will just add HTML on the CLI...)Other PRs and issues related to this:
I'm happy to let the
HttpKernel
to catch the\Throwable
exception right now, but I thought this very conservative PR would have a higher change to get merged.Also note that we do not specify any behaviour on our HttpKernelInterface
To remove the deprecation message you need to add this to your config: