Skip to content
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

Catch error with entrypointlookups in sub-requests #21

Closed
wants to merge 4 commits into from
Closed

Catch error with entrypointlookups in sub-requests #21

wants to merge 4 commits into from

Conversation

ckrack
Copy link

@ckrack ckrack commented Dec 5, 2018

In EntrypointLookup, the list of previously returned entries is not reset
on sub-requests.
This leads to errors when sub-requests return full html pages.

Fixes symfony/demo#910

Twig_Error_Runtime leads to sub-requests.
In EntrypointLookup, the list of previously returned entries is not reset
on these requests.

Fixes symfony/demo#910
This replaces the fix with an ExceptionListener.
When returning full html in a sub-request, already included assets
should not be included again.
@Lyrkan
Copy link
Contributor

Lyrkan commented Dec 5, 2018

I'm wondering if that's the right way to handle that... if a sub-request is created but then popped off the stack you'd go back to the original one with the wrong returned entries, right?

Wouldn't it be better to keep track of the returned entries per request instead?

@ckrack
Copy link
Author

ckrack commented Dec 5, 2018

I'm wondering if that's the right way to handle that... if a sub-request is created but then popped off the stack you'd go back to the original one with the wrong returned entries, right?

Yes, I think so.
It will also have another issue: when a sub-request returns only partial html, but wants to output an additional asset in there, due to the reset all assets would be output again.

Wouldn't it be better to keep track of the returned entries per request instead?
Not sure how this would solve it. When a sub-request overrides the output, it should include all necessary assets. When it just adds some html, it could include more assets but should not include the ones previously output.

Maybe the more specific fix from 6b6b731 is better, as it only covers the use case with Twig_Error_Runtime.

@weaverryan
Copy link
Member

Yea, this is a complex issue - thanks for checking into it @ckrack.

Wouldn't it be better to keep track of the returned entries per request instead?

Yes, I also think this is the best way to do this. I was talking with @ckrack about this, and I thought for a moment that this was NOT the best way - but now I think it is. Basically. the EntrypointLookup should keep track of which assets have been used on a request-by-request basis. We can probably do this by injecting the RequestStack and using the spl_object_hash() as a key for tracking which assets have been returned for that specific request.

There is still another edge-case, but I think it can just be handled by the user (and some documentation): if you render 2 full HTML pages within one sub-request (e.g. render HTML for a PDF, then render the normal template - odd case, but possible), you will need to manually reset the stack.

@ckrack are you able to make the above changes? Thanks

@weaverryan
Copy link
Member

Ping @ckrack! I just merged another PR, which would have probably conflicted with the work that needs to be done here. So, things are clear now. Do you have some time to work on this?

Thanks for the attention!

@weaverryan
Copy link
Member

Ok, on third thought, I think this is the right approach - we cannot predict what behavior is correct for sub-requests in general.

$exception = $event->getException();

// Reset the entrypointLookup list of previously returned entries, as Twig_Error_Runtime will initialise a sub-request
if ($exception instanceof Twig_Error_Runtime) {
Copy link
Member

Choose a reason for hiding this comment

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

Why this error specifically? All exceptions will result in a full page being rendered (by default). So, I think what you’re doing is trying to detect if the error came from Twig, which is the most likely cause of a situation where Encore assets have been rendered already... and THEN an exception happens. Am I right?

If so... I’m not sure it’s a good idea. Regardless of the error, if we try to render a template for an error page, that should probably use a fresh set of Encore assets.

Copy link
Member

Choose a reason for hiding this comment

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

I’m also trying to think if we should limit this to the master request... does the default exception behavior (rendering an error template) happen only on the master request? That seems likely - I just haven’t checked the code yet.

Copy link
Member

Choose a reason for hiding this comment

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

I've thought more about this. I think we should:

  1. Always reset on exception - not just if there was a Twig error. There is going to be some edge cases (people successfully rendering in Twig, then a listener throws an exception after).

  2. We should reset on all requests, not just the master request.

There may still be edge cases - but let's do that and see what happens. Fortunately, this is in "exception" land - so it's already not a normal request.

@weaverryan
Copy link
Member

Also, there is now one more complication: #17 added support for multiple builds. So there is now an EntrypointLookupCollection that can contain multiple EntrypointLookup, and we need to clear all of them (probably will need to add a method to be able to get all of them from that new class).

@weaverryan
Copy link
Member

Ping @ckrack! Are you still able to work on this? Thanks

@emodric
Copy link
Contributor

emodric commented Jun 6, 2019

Hi @weaverryan ! What can be done to move this forward? Can we help?

@weaverryan
Copy link
Member

Closing in favor of #74 - thanks for getting us moving on this @ckrack!

@weaverryan weaverryan closed this Aug 9, 2019
weaverryan added a commit that referenced this pull request Jan 31, 2020
…(tbmatuka)

This PR was squashed before being merged into the master branch (closes #74).

Discussion
----------

Reset default EntrypointLookup on exception to fix #21 and #73

Since @ckrack seems to be unavailable to continue working on #21, I figured this would be faster :)

I don't like having `_default` hardcoded in the listener, but I see no other options right now.
I thought about adding a `resetAll()` method to EntrypointLookupCollection, but there were a couple of issues with that:
1. It would either be a BC break if I added it to the interface, or an important method that isn't interfaced and I don't really like either of those.
2. I couldn't even implement it because the container that we get in the collection only has `has()` and `get()` methods, so I couldn't go through it. This would also have to be replaced (and break BC) to implement `resetAll()`.

Fixes symfony/demo#910

Commits
-------

da36629 Reset default EntrypointLookup on exception to fix #21 and #73
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Tricky error related to 500 error pages
4 participants