-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[HttpKernel] Catch HttpExceptions when templating is not installed #26138
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
junowilderness
commented
Feb 11, 2018
•
edited by nicolas-grekas
Loading
edited by nicolas-grekas
Q | A |
---|---|
Branch? | 3.4 |
Bug fix? | yes |
New feature? | no |
BC breaks? | ? |
Deprecations? | no |
Tests pass? | ? |
Fixed tickets | #25844 |
License | MIT |
Doc PR | symfony/symfony-docs#... |
- Test manually
- Check for BC breaks
- Needs tests
|
||
public function onKernelException(GetResponseForExceptionEvent $event) | ||
{ | ||
if ($this->container->has('twig')) { |
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.
instead we could remove the service definition within a compiler pass? So it would have zero runtime overhead if twig
is available
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.
@dmaicher Thank you for reviewing. Yes, that's a good idea. Do you feel TwigBundle or HttpKernel should have that compiler pass logic? I think TwigBundle but I'd like to hear your opinion.
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 would create the compiler pass inside HttpKernel
and use it accordingly in the FrameworkBundle
like done for example here: https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php#L31
@@ -36,5 +36,9 @@ public function process(ContainerBuilder $container) | |||
$container->removeDefinition('twig.exception_listener'); | |||
} | |||
} | |||
|
|||
if ($container->hasDefinition('twig.exception_listener')) { |
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.
@dmaicher What do you think of putting the responsibility in the existing TwigBundle compiler pass?
I don't understand enough about SF tests to know why tests are failing. |
I'd like to propose an alternative, see #26928. |
#26928 is simpler. |
Reopening as discussed in #26928 |
@@ -67,6 +67,12 @@ | |||
<argument type="service" id="router" on-invalid="ignore" /> | |||
</service> | |||
|
|||
<service id="http_exception_listener" class="Symfony\Component\HttpKernel\EventListener\HttpExceptionListener"> | |||
<tag name="kernel.event_subscriber" /> | |||
<argument type="service" id="service_container" /> |
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.
the argument is never used, it should be removed
<service id="http_exception_listener" class="Symfony\Component\HttpKernel\EventListener\HttpExceptionListener"> | ||
<tag name="kernel.event_subscriber" /> | ||
<argument type="service" id="service_container" /> | ||
<argument>%kernel.debug%</argument> |
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 would not make this depend on the debug parameter, let's remove it.
@@ -36,5 +36,9 @@ public function process(ContainerBuilder $container) | |||
$container->removeDefinition('twig.exception_listener'); | |||
} | |||
} | |||
|
|||
if ($container->hasDefinition('twig.exception_listener')) { | |||
$container->removeDefinition('http_exception_listener'); |
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'd suggest to not conditionally unregister the listener, let it be, that's not a measurable overhead anyway
protected $container; | ||
protected $debug; | ||
|
||
public function __construct(ContainerInterface $container, $debug = false) |
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.
can be removed (alongside with properties) since we're not gonna use it
|
||
public function onKernelException(GetResponseForExceptionEvent $event) | ||
{ | ||
if (!$this->debug) { |
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'd suggest an alternative logic in the method:
when the event already contains a response, this listener should just do nothing.
otherwise and if possible, it would be great if creating the response could be delegated to then ExceptionHandler
(the Debug component is already a required dependency)
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.
(see previous review)
@cilefen up to finish this one? Otherwise no pb, please advise and we'll take over. |
I will look look at it today. |
$flattenException = FlattenException::create($event->getException()); | ||
$handler = new ExceptionHandler(false); | ||
$response = new Response($handler->getContent($flattenException)); | ||
$event->setResponse($response); |
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.
@nicolas-grekas This does not actually work as expected in the dev environment. In fact I do no understand how to detect the environment without injecting it.
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.
@nicolas-grekas ... and indeed I may be way "off the mark" in terms of what you wrote about delegating to the ExceptionHandler.
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.
Actually, I was wrong, kernel.debug
may be required to populate the first argument of ExceptionHandler's constructor.
About the implementation, I suggest to borrow from ExceptionHandler::sendPhpResponse()
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.
@nicolas-grekas hmm but should this new listener really stream/echo the response to the client directly? I think it should just set the response on the event and nothing else?
Edit: I mean its just this line? https://github.com/symfony/symfony/pull/26928/files#diff-3d3b8968ae2d94a9aab7078dec41e607R228
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.
We should not call sendPhpResponse but take inspiration from it. Eg header management is missing right 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.
Ah ok got it 👍 yes makes sense to use HttpExceptionInterface::getHeaders()
also
|
||
public function onKernelException(GetResponseForExceptionEvent $event) | ||
{ | ||
if ($event->hasResponse()) { |
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.
Also I am not sure if this evaluates to true often in the production environment without twig installed.
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 should evaluate to false unless one handled the exception, either via twigbundle or any other mean, isn't it?
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.
@nicolas-grekas The issue at hand is that (I think) there is never a response on $event when twig is not installed. But as I think you mentioned above we need to also check if the environment is debug (in which case the twig debug handler should activate). Does that make sense?
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.
We should forget about Twig here, it's totally independent code. What matters is if there is a listener that already set a response, and if not, then generate one. This question doesn't need to wonder about debug or not.
There are ppl that do set responses here, while not using twig (eg for APIs.)
@dmaicher I'm wondering: the approach with the global exception handler I proposed in the front controller is also able to deal with fatal errors. |
@nicolas-grekas sure let's discuss it 😊
Currently I'm using |
but |
true! I just double checked it and you are right 😉 This particular project was started with Symfony 2.3 ages ago and I remember back then there was some reason for this. But now it works fine 👍 😃 |
I don't have the double display on my side. I'm not testing with Apache but with |
@nicolas-grekas Your diff works for me, and seems simpler. The only question I have in fact is whether it intended that a production environment 404 should look like this: |
yes it is IMHO: we need to provide some default page, we have one in Debug. If this doesn't fit, then we should update Debug (ie fix #22964) |
@nicolas-grekas I see. I've just now switched to your diff. I haven't rebased or squashed yet. |
Thanks. It'd be awesome if you could squash and add a test case if possible... :) |
@nicolas-grekas It is rebased and squashed. I stole the test addition you made in #26928. |
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 stole the test addition you made in #26928.
that didn't work actually as an exception is thrown there.
I pushed a test on your fork instead :)
All good on my side, thank you!
Thank you @cilefen. |
…nstalled (cilefen) This PR was merged into the 3.4 branch. Discussion ---------- [HttpKernel] Catch HttpExceptions when templating is not installed | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | yes | New feature? | no | BC breaks? | ? | Deprecations? | no | Tests pass? | ? | Fixed tickets | #25844 | License | MIT | Doc PR | symfony/symfony-docs#... <!--highly recommended for new features--> - [x] Test manually - [x] Check for BC breaks - [x] Needs tests <!-- - Bug fixes must be submitted against the lowest branch where they apply (lowest branches are regularly merged to upper ones so they get the fixes too). - Features and deprecations must be submitted against the master branch. - Replace this comment by a description of what your PR is solving. --> Commits ------- 4e527aa bug #25844 [HttpKernel] Catch HttpExceptions when templating is not installed
This PR was merged into the 3.4 branch. Discussion ---------- [HttpKernel] fix registering IDE links | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #27194 | License | MIT | Doc PR | - Reverts some changes made in #27074 in `FrameworkBundle::boot()` that create the linked issue. Leverages changes done in #26138 instead. Commits ------- 92e3023 [HttpKernel] fix registering IDE links
…templating is not installed (cilefen)" (nicolas-grekas) This PR was merged into the 3.4 branch. Discussion ---------- Revert "bug #26138 [HttpKernel] Catch HttpExceptions when templating is not installed (cilefen)" | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | yes | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #27212 | License | MIT | Doc PR | - This reverts commit b213c5a, reversing changes made to 61af0e3. This breaks BC and is more like a new feature, let's move this on master. Commits ------- c6acad7 Revert "bug #26138 [HttpKernel] Catch HttpExceptions when templating is not installed (cilefen)"
* 3.4: Revert "bug #26138 [HttpKernel] Catch HttpExceptions when templating is not installed (cilefen)"
* 4.0: Revert "bug #26138 [HttpKernel] Catch HttpExceptions when templating is not installed (cilefen)"
* 4.1: Revert "bug #26138 [HttpKernel] Catch HttpExceptions when templating is not installed (cilefen)"