Problem/Motivation
When a Single Directory Component (SDC) fails prop validation during development, Drupal throws an InvalidComponentException. However, the generated stack trace is often notoriously difficult to debug because the underlying compiled Twig classes are only listed as hashes (e.g., __TwigTemplate_37dfef847a6375fdc2b31820ed3a5cd2).
The error message states which component failed, but completely conceals where (in which parent theme/module Twig file) that component was actually embedded or included. In complex layouts with highly nested components, finding the culprit becomes a guessing game.
In our case this was the (not very helpful) error message shown
Drupal\Core\Render\Component\Exception\InvalidComponentException: [radix:card/card_subtitle] NULL value found, but a string or an object is required. This may be because the property is empty instead of having data present. If possible fix the source data, use the |default() twig filter, or update the schema to allow multiple types.. [radix:card/card_subtitle_utility_classes] NULL value found, but an array or an object is required. in Drupal\Core\Theme\Component\ComponentValidator->validateProps() (line 243 of core/lib/Drupal/Core/Theme/Component/ComponentValidator.php).
Steps to reproduce
Have a broken / incompatible SDC call, e.g. by updating theme. We had this several times updating Radix for example, but I guess there are several ways to experience this.
Proposed resolution
Enhance Drupal\Core\Template\ComponentsTwigExtension::doValidateProps() to intercept the InvalidComponentException. Inside the catch block, we can inspect the debug_backtrace() to find the first Twig\Template instance that is not the component template itself. By utilizing Twig's native getTemplateName() method, we can extract the precise file path of the calling template and prepend it to the exception message.
Remaining tasks
The result of the fix is
Drupal\Core\Render\Component\Exception\InvalidComponentException: Component validation failed in Twig file [themes/custom/my_theme/templates/content/taxonomy-term--card.html.twig] for component [radix:card]: [radix:card/card_subtitle] NULL value found, but a string or an object is required. This may be because the property is empty instead of having data present. If possible fix the source data, use the |default() twig filter, or update the schema to allow multiple types.. [radix:card/card_subtitle_utility_classes] NULL value found, but an array or an object is required. in Drupal\Core\Template\ComponentsTwigExtension->doValidateProps() (line 152 of core/lib/Drupal/Core/Template/ComponentsTwigExtension.php).
which shows the affected twig templates and helps fixing the issue efficiently.
Remaining tasks
- Discuss
- Implement
- Review
- Release
User interface changes
Introduced terminology
API changes
Data model changes
Release notes snippet
| Comment | File | Size | Author |
|---|
Issue fork drupal-3611957
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
anybodyComment #3
anybodyComment #5
anybodyHere we go, if anyone has a better way to add the super helpful template path, please let me know. Without this it's super hard to debug such issues and find the root cause. Theme developers are going crazy ;)
Comment #6
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #7
anybodyComment #8
anybodyI guess this should have a test, but would be great to get maintainer feedback on the general approach first, before we move forward.
Comment #9
thomas.frobieterWorks perfectly fine for the described case.
Of course, it's so frustrating. This can mean the difference between debugging for an hour or a minute.
Comment #10
catchI think it's reasonable to do the backtrace here, but agreed with #8 that it should come with test coverage since there's a fair bit of logic involved here. The worst that can happen is a different fatal error instead of the current exception, but would be good to keep it working.
Comment #12
grevil commentedDone! I added a test, containing an invalid component (missing ctaText) and check, whether the the error message contains the error calling template, as well as the component, whose props actually fail validation.
Please review!
Comment #13
needs-review-queue-bot commentedThe Needs Review Queue Bot tested this issue. It fails the Drupal core commit checks. Therefore, this issue status is now "Needs work".
This does not mean that the patch necessarily needs to be re-rolled or the MR rebased. Read the Issue Summary, the issue tags and the latest discussion here to determine what needs to be done.
Consult the Drupal Contributor Guide to find step-by-step guides for working with issues.
Comment #14
grevil commentedComment #15
grevil commentedAll green!
Comment #16
anybodyGreat work, thanks for resolving #10!
All fine now @catch?