Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[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

Merged
merged 1 commit into from
Jun 25, 2022

Conversation

Nyholm
Copy link
Member

@Nyholm Nyholm commented Apr 11, 2022

Q A
Branch? 6.2
Bug fix? no
New feature? no
Deprecations? yes
Tickets Fix #16205
License MIT
Doc PR symfony/symfony-docs#...

I suggest that starting from Symfony 7.0 the HttpKernel will start to catch \Throwable and convert them to a Response.

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:

$kernel = new Kernel('prod', false);
while (true) {
  $request = /* create sf request from custom environment */
  try {
    $response = $kernel->handle(request);
    return ResponseConverter::convert($response);
  } catch (\Throwable $e) {
    exit(1);
  }
}

(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:

framework:
    catch_all_throwables: true

@stof
Copy link
Member

stof commented Apr 11, 2022

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.

@Nyholm
Copy link
Member Author

Nyholm commented Apr 11, 2022

Hm. You are very correct. Thank you. Do you have a suggestion on how to make an opt-in?

@stof
Copy link
Member

stof commented Apr 11, 2022

Well, you would need some kind of configuration parameter that can turn on the catching of errors.

@Nyholm
Copy link
Member Author

Nyholm commented Apr 23, 2022

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.

@Nyholm Nyholm requested review from wouterj and chalasr as code owners April 24, 2022 08:18
@Nyholm Nyholm force-pushed the http-kernel-throwable branch from f806125 to e414827 Compare April 24, 2022 08:45
@Nyholm
Copy link
Member Author

Nyholm commented Apr 24, 2022

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?

@derrabus
Copy link
Member

Thank you very much for bringing this topic up again. I like how you allow to opt-in to the new behavior.

PHPUnit 8.1 low-deps fails because of this PR. Any suggestions how I could fix them?

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.

@Nyholm
Copy link
Member Author

Nyholm commented Apr 24, 2022

Thank you for the feedback. I've updated the PR.

@Nyholm Nyholm force-pushed the http-kernel-throwable branch from 67077c1 to 08ce868 Compare May 1, 2022 07:57
@Nyholm
Copy link
Member Author

Nyholm commented May 1, 2022

The PR is rebased and updated.

status: Waiting for review

@fabpot fabpot modified the milestones: 6.1, 6.2 May 20, 2022
@Nyholm Nyholm force-pushed the http-kernel-throwable branch 4 times, most recently from 77bb69f to a5acdbb Compare May 29, 2022 11:12
@Nyholm
Copy link
Member Author

Nyholm commented May 29, 2022

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

@Nyholm
Copy link
Member Author

Nyholm commented May 29, 2022

Thank you for the review. I've applied the changes.

@carsonbot carsonbot changed the title Add deprecation warning to show HttpKernel::handle() will catch throwables [FrameworkBundle][HttpKernel] Add deprecation warning to show HttpKernel::handle() will catch throwables Jun 14, 2022
public static function getExceptions(): array
{
$exceptions = self::$exceptions;
self::$exceptions = [];
Copy link
Member

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.

Copy link
Member Author

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()

Copy link
Member

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()?

@Nyholm
Copy link
Member Author

Nyholm commented Jun 16, 2022

I've applied all changes and the CI is green

@Nyholm Nyholm force-pushed the http-kernel-throwable branch from 98e1a72 to a906e6c Compare June 16, 2022 16:30
@Nyholm
Copy link
Member Author

Nyholm commented Jun 16, 2022

I've applied the suggested changes. I've rebased the PR and the tests are green.

Could I get a final round of reviews?

Copy link
Contributor

@HeahDude HeahDude left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

{
$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);
Copy link
Contributor

@HeahDude HeahDude Jun 16, 2022

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.

Copy link
Member Author

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?

Copy link
Contributor

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.

Copy link
Member Author

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?

Copy link
Contributor

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.

Copy link
Contributor

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.

@HeahDude
Copy link
Contributor

It would be nice to have this default to true with the 6.2 recipe for new projects (and smooth upgrade with composer recipes:update).

@OskarStark OskarStark changed the title [FrameworkBundle][HttpKernel] Add deprecation warning to show HttpKernel::handle() will catch throwables [FrameworkBundle][HttpKernel] Add deprecation warning to show HttpKernel::handle() will catch throwables Jun 16, 2022
@Nyholm Nyholm force-pushed the http-kernel-throwable branch from 96fefac to 7977a15 Compare June 25, 2022 07:18
@Nyholm
Copy link
Member Author

Nyholm commented Jun 25, 2022

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.

@fabpot
Copy link
Member

fabpot commented Jun 25, 2022

Thank you @Nyholm.

@Nyholm
Copy link
Member Author

Nyholm commented Jun 25, 2022

Awesome. Thank you for merging.

Big thank you to all reviewers too

nicolas-grekas added a commit that referenced this pull request Oct 18, 2022
…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`
weaverryan added a commit to symfony/webpack-encore-bundle that referenced this pull request Oct 19, 2022
…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
@fabpot fabpot mentioned this pull request Oct 24, 2022
Keemosty12 added a commit to Keemosty12/webpack-encore-bundle that referenced this pull request Jun 12, 2025
…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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[HttpKernel] Exceptions Responses are automatically sent
8 participants