Correctly handle cache data instead of throwing an Exception in EarlyRenderingControllerWrapperSubscriber()

Created on 21 December 2015, about 9 years ago
Updated 29 April 2024, 8 months ago

Problem/Motivation

I've spent too many hours debugging that LogicException and finding the root cause now, so I thought it's time to open this issue.

Finding the root cause for that is very hard and frustrating, and there really isn't a good reason to die hard, since all the information is there that we need, it's just not done 100% properly.

To give some ideas what I had to do:
* In Monitoring in a rest service, I'm calling hook_requirements() and because system_requirements() creates a URL for the cron link, I have to add 10+ lines of code to execute it in my own render execution wrapper. I've also helped 2+ people in IRC that did run into similar problems
* In a payment response processing, I'm saving a node, that node is indexed by search API, and then the solr backend generates a URL to figure out the current domain, so it can index for that. I couldn't care less what it does there, but it completely breaks my page and I have no way of fixing that except changing search_api_solr or executing my node save in such a render execution wrapper.

The exception does not give *any* information about what the missing cacheability it is, where it is coming from and how to fix it. You need to debug that yourself, for example by figuring out what max-age/context/tag bubbled up and then break on Cache::merge*() or similar places and then backtracking. Not many developers will figure that out, you need to know lots of internal stuff.

Also, all the required information *is* present, and for render arrays, we happy accept it and move on, only in case of Response objects, we die with an exception.

Workaround

- See change record All rendering must happen in a render context, early rendering's metadata no longer lost
- #19
- #20
- Matt Oliveira @ https://www.lullabot.com/articles/early-rendering-a-lesson-in-debugging-...
-#33
-#47

Proposed resolution

Remove the exception, just add the cacheability metadata, or ignore it with a warning log message or so if that's not possible.

And if the response object is *not* cacheable, then the exception is completely pointless anyway. This is also related to #2626298: REST module must cache only responses to GET requests and would fix that in a more generic way.

Maybe we could introduce some sort of check again later, as an assert or so.

Remaining tasks

User interface changes

API changes

Data model changes

📌 Task
Status

Fixed

Version

10.3

Component
Render 

Last updated 3 days ago

Created by

🇨🇭Switzerland berdir Switzerland

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • 🇺🇸United States smustgrave

    The last patch seemed to have failures. Which makes me think it will need it's own tests as it's breaking the existing ones.

  • 🇮🇳India anisha786

    <strong>Drupal :9.5.9

    Module : Rest Block Layout

    Issue when Api call /block-layout?_format=json&path=/test It is giving error Previously on drupal 8.7.5 it is working fine but after version updation it is giving error

    Error Message
    : LogicException: The controller result claims to be providing

    relevant cache metadata, but leaked metadata was detected. Please
    ensure you are not rendering content too early. Returned object class:
    Drupal\rest\ResourceResponse. in
    Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext()
    (line 158 of
    \core\lib\Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber.php).
    I have applied below #43 mentioned patch but from below patch error is gone , but in my website if user view multiple pages in separate tabs it is showing wrong node content data. It shows data which was latest cached.
    . Let me know if anyone has solution how to fix it .

  • 🇫🇷France damien laguerre

    Idem, #43 solved my problem.
    I'm experiencing this problem in a REST resource. The context user.node_grants:view throws this error.

  • Patch #43 still applies to 10.3.x. However, it should probably be converted to a merge request.

  • solideogloria changed the visibility of the branch 2638686-exception-in-earlyrenderingcontrollerwrappersubscriber to hidden.

  • The new merge request targets 11.x and has the changes from patch #43, as well as the change I mentioned in #66.

  • Pipeline finished with Failed
    8 months ago
    Total: 989s
    #153517
  • Status changed to Needs review 8 months ago
  • I fixed the broken test. It just needed to be updated, since the code changes result in a success response instead of an HTTP 500.

  • Please review the changes and check whether the test coverage for early rendering needs to be expanded to handle more cases.

  • Pipeline finished with Success
    8 months ago
    Total: 987s
    #153576
  • 🇺🇸United States smustgrave

    smustgrave changed the visibility of the branch 11.x to hidden.

  • 🇺🇸United States smustgrave

    smustgrave changed the visibility of the branch 10.3.x to hidden.

  • 🇺🇸United States smustgrave

    smustgrave changed the visibility of the branch 10.1.x to hidden.

  • 🇺🇸United States smustgrave

    smustgrave changed the visibility of the branch 10.2.x to hidden.

  • Status changed to RTBC 8 months ago
  • 🇺🇸United States smustgrave

    Hiding patches and empty branches

    Ran test-only feature to confirm coverage

    1) Drupal\Tests\system\Functional\Common\EarlyRenderingControllerTest::testEarlyRendering
    Behat\Mink\Exception\ExpectationException: Current response status code is 500, but 200 expected.
    /builds/issue/drupal-2638686/vendor/behat/mink/src/WebAssert.php:888
    /builds/issue/drupal-2638686/vendor/behat/mink/src/WebAssert.php:145
    /builds/issue/drupal-2638686/core/modules/system/tests/src/Functional/Common/EarlyRenderingControllerTest.php:76
    /builds/issue/drupal-2638686/vendor/phpunit/phpunit/src/Framework/TestResult.php:729
    ERRORS!
    Tests: 1, Assertions: 27, Errors: 1.
    

    believe the issue summary proposed solution lines up with moving the CacheableResponseInterface up to it's own check.

    Believe this is good and has gotten a few comments about it working for others.

  • 🇺🇸United States dww

    I landed here chasing various things. For how long this issue has been open, how many comments, patches and effort went into this, I was amazed / shocked / delighted / heartbroken that the diffstat on the changes tab in the MR is: +7 / - 3. 😂 Thrilled to see it's actually RTBC at this point, and hopefully going to land soon. +1 to the RTBC. The code changes are great. The test change is that we now get to check for better outcomes to a common DX problem. 🚀 it!

    Thanks,
    -Derek

    p.s. Starting to save credit. Could use a closer look before commit.

  • 🇺🇸United States dww

    Hate to ask, but do we need a change record for this?

  • Status changed to Needs work 8 months ago
  • 🇳🇿New Zealand quietone

    The title of this does not match what I read in the patch, it is not removing an exception. I went to improve that using information in the proposed resolution. However, that describes some options. So, I am sadly setting back to NW for a descriptive title and a tweak to the proposed resolution so that it what is being changed.

  • Status changed to Needs review 8 months ago
  • 🇺🇸United States dww

    I opened an MR thread to document how the diff is removing an exception. I'm a little sad to change the title at all, but how's this?

  • I think the new title is acceptable.

  • Status changed to RTBC 8 months ago
  • 🇺🇸United States smustgrave

    Title update seems good.

  • 🇬🇧United Kingdom catch

    I reread this a fair bit.

    I think given we have all the information here, and a way to apply it to the response, it's fine to do that and not throw the exception. As discussed in the issue, if we were able to inform developers at development time via an assertion or useful error message that stuff isn't being passed around correctly, that might be better, but there's no solution for this in several years now. The exception hitting on runtime with no obvious way to debug doesn't help anyone.

    I wonder how many people will hit the remaining exception here, but I guess we'll find out whether that's an issue or not down the line.

    Tried to do my best with issue credit but it's a very long issue so apologies if anyone was overlooked.

    Committed/pushed to 11.x and cherry-picked to 10.3.x, thanks!

  • Status changed to Fixed 8 months ago
    • catch committed bd2add4c on 10.3.x
      Issue #2638686 by solideogloria, garphy, loziju, smustgrave, roderik,...
    • catch committed c0d8b4bb on 11.x
      Issue #2638686 by solideogloria, garphy, loziju, smustgrave, roderik,...
    • catch committed c0d8b4bb on 11.0.x
      Issue #2638686 by solideogloria, garphy, loziju, smustgrave, roderik,...
Production build 0.71.5 2024