"A #lazy_builder callback's context may only contain scalar values or NULL" assertion should say which parameter is the problem

Created on 19 June 2024, 6 months ago
Updated 14 August 2024, 4 months ago

Problem/Motivation

This code in Renderer is being too clever:

      assert(count($elements['#lazy_builder'][1]) === count(array_filter($elements['#lazy_builder'][1], function ($v) {
        return is_null($v) || is_scalar($v);
      })), "A #lazy_builder callback's context may only contain scalar values or NULL.");

Instead of a fancy count and array_filter callback, just use a plain foreach, and that way the assertion can say which parameter is the problem.

It's not always clear from looking at the code which thing is not a scalar!

Steps to reproduce

Make a render array with a #lazy_builder element and put an object or an array as one of the parameters.

Proposed resolution

Change the assertion message to give the index of the parameter causing the problem.

Remaining tasks

Answer #8
Manual testing

User interface changes

API changes

Data model changes

Release notes snippet

🐛 Bug report
Status

Needs work

Version

11.0 🔥

Component
Render 

Last updated 5 days ago

Created by

🇬🇧United Kingdom joachim

Live updates comments and jobs are added and updated live.
  • Novice

    It would make a good project for someone who is new to the Drupal contribution process. It's preferred over Newbie.

Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @joachim
  • First commit to issue fork.
  • Pipeline finished with Success
    6 months ago
    Total: 595s
    #203094
  • Status changed to Needs review 6 months ago
  • 🇲🇽Mexico GafgarionMorua Puerto Vallarta
  • Status changed to Needs work 6 months ago
  • 🇺🇸United States smustgrave

    Didn't review but MR should be against 11.x vs 11.0.x

    As the author should be able to update the target, probably will require a rebase.

  • Pipeline finished with Canceled
    6 months ago
    Total: 558s
    #203125
  • Pipeline finished with Success
    6 months ago
    #203133
  • Status changed to Needs review 6 months ago
  • 🇲🇽Mexico GafgarionMorua Puerto Vallarta

    Hello!

    I changed the base of the MR from 11.0.x to 11.x.

    Please review the changes and let me know if additional work is required.

    Kind regards!

  • 🇺🇸United States smustgrave

    So asked @larowlan about this and he mentioned this change now introduces run-time code, while the code in HEAD is optimized by PHP when asserts are off (as they should be in production)

    Not sure a path forward here

  • Status changed to Needs work 6 months ago
  • 🇺🇸United States smustgrave

    So it's possible this is a works as designed

    Not disagreeing it's difficult to read, but if it's to change think we need make sure it's not a performance hit.

  • 🇬🇧United Kingdom joachim

    Ah that is a point I'd not thought of!

    I wonder if there's a way we can get a list of failing keys into the assert message.

  • 🇬🇧United Kingdom joachim

    We could do a dummy outer assert like this:

    assert(array_walk($elements['#lazy_builder'][1], function ($v, $key) {
      assert(is_null($v) || is_scalar($v), "message can now give the $key);
    }, 'This message never gets output);
    
  • Pipeline finished with Success
    6 months ago
    Total: 586s
    #204133
  • Status changed to Needs review 6 months ago
  • 🇲🇽Mexico GafgarionMorua Puerto Vallarta

    Hello again!

    I modified the code to utilize array_walk function as suggested for a clearer error message.

    Please check the changes when you have a minute, and let me know if additional work is required.

    Kind regards!

  • Pipeline finished with Success
    6 months ago
    Total: 652s
    #204980
  • Status changed to Needs work 6 months ago
  • 🇺🇸United States smustgrave

    For good practice can the issue summary be updated to include proposed solution/how this makes things better. Again for practice

  • Status changed to Needs review 6 months ago
  • 🇬🇧United Kingdom joachim

    Done.

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

    Thanks @joachim!

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

    I read the IS, comments and MR. Everything looks fine here expect that I did not find an answer to the question in #8, about performance. Also, there should be manual testing of this change.

    Back to NW for two small tasks.

  • Status changed to RTBC 5 months ago
  • 🇬🇧United Kingdom joachim

    Performance is unchanged, as it's still a single assert().

    The potential performance change was my initial suggestion to put a foreach() loop with the assert() inside.

  • Status changed to Needs work 4 months ago
  • 🇬🇧United Kingdom longwave UK

    RendererPlaceholdersTest::testNonScalarLazyBuilderCallbackContext() should be expanded to cover the updated message, which will also alleviate the need for manual testing.

  • 🇮🇳India santhosh@21

    I am working on this issue

  • 🇬🇧United Kingdom mc_drupal Oxford, UK

    We are working on this issue.

    Goal is to update the run the test on RendererPlaceholdersTest::testNonScalarLazyBuilderCallbackContext and ensure it passes with the appropriate messages

  • 🇬🇧United Kingdom mc_drupal Oxford, UK

    We worked on this issues as part of DrupalCon. We updated the exception message to be more specific. Please could review our change.

  • 🇬🇧United Kingdom joachim

    Looks good.

    I'd nitpick over 'Utilise' instead of the most simple 'Use', but a) not worth changing and b) I can't remember which bits of this MR I worked but it's possible it's me who put that in :)

    I can't RTBC as it was me who suggested the dummy outer assert.

  • Pipeline finished with Failed
    3 months ago
    Total: 547s
    #294247
  • 🇬🇧United Kingdom opdavies Wales

    The GitLab CI pipeline is failing due to a test failure.

    There was 1 failure:

    1)
    Drupal\Tests\layout_builder\FunctionalJavascript\BlockFilterTest::testBlockFilter
    Failed asserting that actual size 1 matches expected size 0.

    /builds/issue/drupal-3455746/core/modules/layout_builder/tests/src/FunctionalJavascript/BlockFilterTest.php:134

    FAILURES!
    Tests: 1, Assertions: 26, Failures: 1.

  • 🇬🇧United Kingdom opdavies Wales

    Is this a regression caused by the changes to the assertion in the earlier commits?

Production build 0.71.5 2024