Problem/Motivation

Found gazillions of errors in our watchdog. Debugging shows that a template fallback like this triggered ComponentLoader to log them:

{% include ['c4c:state-transition-help--' ~ workflowId, 'c4c:state-transition-help']

The offending code from \Drupal\Core\Template\Loader\ComponentLoader::exists:

  public function exists($name): bool {
    if (!preg_match('/^[a-zA-Z][a-zA-Z0-9:_-]*[a-zA-Z0-9]?$/', $name)) {
      return FALSE;
    }
    try {
      $this->pluginManager->find($name);
      return TRUE;
    }
    catch (ComponentNotFoundException $e) {
      Error::logException($this->logger, $e);
      return FALSE;
    }
  }

Steps to reproduce

See above.

Proposed resolution

Drop the Error::logException line without replacement.
Simply checking the existence of a component should not flood the dblog.

As a bonus, remove the internal findTemplate() function which is unused.

Remaining tasks

Code, review, commit.

User interface changes

None.

Introduced terminology

None.

API changes

None.

Data model changes

None.

Release notes snippet

None.

Issue fork drupal-3488260

Command icon 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

geek-merlin created an issue. See original summary.

geek-merlin’s picture

Full error and trace:

Drupal\Core\Render\Component\Exception\ComponentNotFoundException: Unable to find component "c4c:state-transition-help--c4c_product" in the component repository. [The "c4c:state-transition-help--c4c_product" plugin does not exist. Valid plugin IDs for Drupal\Core\Theme\ComponentPluginManager are: navigation:toolbar-button, c4c:c4c-dash-stores, c4c:c4c-dash-products, c4c:c4c-dash-loan-limited, c4c:c4c-dash-deposits, c4c:c4c-dash-todo, c4c:c4c-dash-contacts, c4c:c4c-dash-wrapper, c4c:c4c-dash-submissions, c4c:state-transition-option, c4c:state-transition-formatter, c4c:state-transition-option-list, c4c:state-transition-help, c4c:state-transition-option-lists, c4c:disclose, c4c:disclose-help, c4c:disclose-edit, olivero:teaser] in Drupal\Core\Theme\ComponentPluginManager->createInstance() (line 118 of web/core/lib/Drupal/Core/Theme/ComponentPluginManager.php).


Backtrace	
#0 web/core/lib/Drupal/Core/Theme/ComponentPluginManager.php(139): Drupal\Core\Theme\ComponentPluginManager->createInstance()
#1 web/core/lib/Drupal/Core/Template/Loader/ComponentLoader.php(73): Drupal\Core\Theme\ComponentPluginManager->find()
#2 vendor/twig/twig/src/Loader/ChainLoader.php(87): Drupal\Core\Template\Loader\ComponentLoader->exists()
#3 vendor/twig/twig/src/Environment.php(480): Twig\Loader\ChainLoader->exists()
#4 vendor/twig/twig/src/Template.php(284): Twig\Environment->resolveTemplate()
#5 web/sites/default/files/php/twig/67378f97837bb_c4c:state-transition-form_MxcrkH4mxXQ-j3yNe7MvA5dcs/fwFCXY9fWd-nlDZd68es-21dTjo-Isaco2sckds-PRQ.php(182): Twig\Template->loadTemplate()
#6 vendor/twig/twig/src/Template.php(437): __TwigTemplate_9a5d9baeddf4125a0fced8b9cb5b502a___1869349367->block_content()
#7 vendor/twig/twig/src/Template.php(145): Twig\Template->yieldBlock()
#8 vendor/twig/twig/src/Template.php(206): Twig\Template->displayBlock()
#9 web/sites/default/files/php/twig/67378f97837bb_c4c:disclose-help_qGblSbwRYDcFnNy828ygtEOe1/sS0pDGOGxuk9-bo-gKRrne-OJHl1sVU_lK0aQsANW2o.php(51): Twig\Template->renderBlock()
#10 vendor/twig/twig/src/Extension/CoreExtension.php(1967): __TwigTemplate_98defebf1e93cb711dd6540015684b77->{closure}()
#11 web/sites/default/files/php/twig/67378f97837bb_c4c:disclose-help_qGblSbwRYDcFnNy828ygtEOe1/sS0pDGOGxuk9-bo-gKRrne-OJHl1sVU_lK0aQsANW2o.php(48): Twig\Extension\CoreExtension::captureOutput()
#12 vendor/twig/twig/src/Template.php(393): __TwigTemplate_98defebf1e93cb711dd6540015684b77->doDisplay()
#13 web/sites/default/files/php/twig/67378f97837bb_c4c:state-transition-form_MxcrkH4mxXQ-j3yNe7MvA5dcs/fwFCXY9fWd-nlDZd68es-21dTjo-Isaco2sckds-PRQ.php(169): Twig\Template->yield()
#14 vendor/twig/twig/src/Template.php(393): __TwigTemplate_9a5d9baeddf4125a0fced8b9cb5b502a___1869349367->doDisplay()
#15 web/sites/default/files/php/twig/67378f97837bb_c4c:state-transition-form_MxcrkH4mxXQ-j3yNe7MvA5dcs/fwFCXY9fWd-nlDZd68es-21dTjo-Isaco2sckds-PRQ.php(55): Twig\Template->yield()
#16 vendor/twig/twig/src/Extension/CoreExtension.php(1967): __TwigTemplate_9a5d9baeddf4125a0fced8b9cb5b502a->{closure}()
#17 web/sites/default/files/php/twig/67378f97837bb_c4c:state-transition-form_MxcrkH4mxXQ-j3yNe7MvA5dcs/fwFCXY9fWd-nlDZd68es-21dTjo-Isaco2sckds-PRQ.php(48): Twig\Extension\CoreExtension::captureOutput()
#18 vendor/twig/twig/src/Template.php(393): __TwigTemplate_9a5d9baeddf4125a0fced8b9cb5b502a->doDisplay()
#19 web/sites/default/files/php/twig/67378f97837bb___string_template__aacdbc_L9-lvlayo6eN8GigUwpfZV2IE/ZLOc-K5NEbq26FzUaFAaTMNppd7zuK4NYmRwLVhP5jk.php(130): Twig\Template->yield()
#20 vendor/twig/twig/src/Template.php(393): __TwigTemplate_4ba91fed2d9b6dd3a1d23364e8fabcda___64313199->doDisplay()
#21 web/sites/default/files/php/twig/67378f97837bb___string_template__aacdbc_L9-lvlayo6eN8GigUwpfZV2IE/ZLOc-K5NEbq26FzUaFAaTMNppd7zuK4NYmRwLVhP5jk.php(44): Twig\Template->yield()
#22 vendor/twig/twig/src/Template.php(393): __TwigTemplate_4ba91fed2d9b6dd3a1d23364e8fabcda->doDisplay()
#23 vendor/twig/twig/src/Template.php(349): Twig\Template->yield()
#24 vendor/twig/twig/src/Template.php(364): Twig\Template->display()
#25 vendor/twig/twig/src/TemplateWrapper.php(35): Twig\Template->render()
#26 web/core/lib/Drupal/Core/Template/TwigEnvironment.php(234): Twig\TemplateWrapper->render()
#27 web/modules/custom/twig_strict/src/TwigEnvironment/TwigStrictEnvironmentTrait.php(54): Drupal\Core\Template\TwigEnvironment->renderInline()
#28 web/core/lib/Drupal/Core/Render/Element/InlineTemplate.php(54): Drupal\Core\Template\TwigEnvironment\__use\Drupal\twig_strict\TwigEnvironment\TwigStrictEnvironmentTrait->renderInline()
#29 [internal function]: Drupal\Core\Render\Element\InlineTemplate::preRenderInlineTemplate()
#30 web/core/lib/Drupal/Core/Security/DoTrustedCallbackTrait.php(113): call_user_func_array()
#31 web/core/lib/Drupal/Core/Render/Renderer.php(870): Drupal\Core\Render\Renderer->doTrustedCallback()
#32 web/core/lib/Drupal/Core/Render/Renderer.php(432): Drupal\Core\Render\Renderer->doCallback()
#33 web/core/lib/Drupal/Core/Render/Renderer.php(504): Drupal\Core\Render\Renderer->doRender()
#34 web/core/lib/Drupal/Core/Render/Renderer.php(248): Drupal\Core\Render\Renderer->doRender()
#35 web/core/lib/Drupal/Core/Template/TwigExtension.php(476): Drupal\Core\Render\Renderer->render()
#36 web/sites/default/files/php/twig/67378f97837bb_field.html.twig_951wjTAjxAQzDPd8iCs6h4TzC/T0J8I7T9jw9SG2hSY1zn66tN532aB5fNNAupJPX3ZG4.php(130): Drupal\Core\Template\TwigExtension->escapeFilter()
#37 vendor/twig/twig/src/Template.php(393): __TwigTemplate_593909c9f0ed964d0cacfa2423bbbe31->doDisplay()
#38 vendor/twig/twig/src/Template.php(349): Twig\Template->yield()
#39 vendor/twig/twig/src/Template.php(364): Twig\Template->display()
#40 vendor/twig/twig/src/TemplateWrapper.php(35): Twig\Template->render()
#41 web/core/themes/engines/twig/twig.engine(33): Twig\TemplateWrapper->render()
#42 web/core/lib/Drupal/Core/Theme/ThemeManager.php(348): twig_render_template()
#43 web/core/lib/Drupal/Core/Render/Renderer.php(491): Drupal\Core\Theme\ThemeManager->render()
#44 web/core/lib/Drupal/Core/Render/Renderer.php(504): Drupal\Core\Render\Renderer->doRender()
#45 web/core/lib/Drupal/Core/Render/Renderer.php(248): Drupal\Core\Render\Renderer->doRender()
#46 web/core/lib/Drupal/Core/Template/TwigExtension.php(476): Drupal\Core\Render\Renderer->render()
#47 web/sites/default/files/php/twig/67378f97837bb_commerce-product.html.twi_tOcY0iAUkU2l2fGSXjABAM7dg/LWE4gyDVD4X69M9JGRQqHbVHWfMTgGEmWyZVEt4T7Ts.php(55): Drupal\Core\Template\TwigExtension->escapeFilter()
#48 vendor/twig/twig/src/Template.php(393): __TwigTemplate_7a8da07bbb553fd7798ee89961aade03->doDisplay()
#49 vendor/twig/twig/src/Template.php(349): Twig\Template->yield()
#50 vendor/twig/twig/src/Template.php(364): Twig\Template->display()
#51 vendor/twig/twig/src/TemplateWrapper.php(35): Twig\Template->render()
#52 web/core/themes/engines/twig/twig.engine(33): Twig\TemplateWrapper->render()
#53 web/core/lib/Drupal/Core/Theme/ThemeManager.php(348): twig_render_template()
#54 web/core/lib/Drupal/Core/Render/Renderer.php(491): Drupal\Core\Theme\ThemeManager->render()
#55 web/core/lib/Drupal/Core/Render/Renderer.php(248): Drupal\Core\Render\Renderer->doRender()
#56 web/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php(238): Drupal\Core\Render\Renderer->render()
#57 web/core/lib/Drupal/Core/Render/Renderer.php(638): Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}()
#58 web/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php(231): Drupal\Core\Render\Renderer->executeInRenderContext()
#59 web/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php(128): Drupal\Core\Render\MainContent\HtmlRenderer->prepare()
#60 web/core/lib/Drupal/Core/EventSubscriber/MainContentViewSubscriber.php(90): Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse()
#61 [internal function]: Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray()
#62 web/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php(111): call_user_func()
#63 vendor/symfony/http-kernel/HttpKernel.php(186): Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch()
#64 vendor/symfony/http-kernel/HttpKernel.php(76): Symfony\Component\HttpKernel\HttpKernel->handleRaw()
#65 web/core/lib/Drupal/Core/StackMiddleware/Session.php(53): Symfony\Component\HttpKernel\HttpKernel->handle()
#66 web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(48): Drupal\Core\StackMiddleware\Session->handle()
#67 web/core/lib/Drupal/Core/StackMiddleware/ContentLength.php(28): Drupal\Core\StackMiddleware\KernelPreHandle->handle()
#68 web/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\Core\StackMiddleware\ContentLength->handle()
#69 web/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass()
#70 web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Drupal\page_cache\StackMiddleware\PageCache->handle()
#71 web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle()
#72 web/core/lib/Drupal/Core/StackMiddleware/AjaxPageState.php(36): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle()
#73 web/core/lib/Drupal/Core/StackMiddleware/StackedHttpKernel.php(51): Drupal\Core\StackMiddleware\AjaxPageState->handle()
#74 web/core/lib/Drupal/Core/DrupalKernel.php(741): Drupal\Core\StackMiddleware\StackedHttpKernel->handle()
#75 web/index.php(19): Drupal\Core\DrupalKernel->handle()
#76 web/.ht.router.php(71): require('...')
#77 {main}

kensae’s picture

@geek-merlin I discovered the same issue (https://www.drupal.org/project/drupal/issues/3530032)
Your solution also fixes the issue.

geek-merlin’s picture

Status: Active » Needs work

Setting NW to update the tests.

geek-merlin’s picture

Title: Checking if component exists logs error » Checking if component exists logs error (e.g. in include([template, fallback])

See related issue.

geek-merlin’s picture

Status: Needs work » Reviewed & tested by the community

Patch is trivial and removes a log that should not be logged. I suppose it does not need a test, as similar patches do not have them.
Tests are green. Setting rtbc per #4.

geek-merlin’s picture

Component: theme system » single-directory components
longwave’s picture

Status: Reviewed & tested by the community » Needs work

This was the only use of $this->logger so that can be dropped from the constructor as well.

longwave’s picture

Status: Needs work » Needs review

Removed the logger from the constructor and the test.

Also noticed that findTemplate() isn't part of the interface and appears to be never be called, so I removed that as well.

dcam’s picture

Issue summary: View changes
Status: Needs review » Reviewed & tested by the community

I'm fairly certain the parameter doesn't need to be deprecated. But I don't know if this needs a change record or not as an API change. Something to consider. Otherwise, the changes are simple enough. I'll RTBC it.

I updated the issue summary with the info about removing findTemplate().

quietone’s picture

Title: Checking if component exists logs error (e.g. in include([template, fallback]) » Stop logging an error when component not found

A better title?

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.

needs-review-queue-bot’s picture

Status: Reviewed & tested by the community » Needs work
StatusFileSize
new955 bytes

The 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.

dcam’s picture

Status: Needs work » Reviewed & tested by the community

Post-bot-rebellion rebase

nod_’s picture

Not sure about this. What if you expect the template to be loaded but it's not, how do you figure that out as a frontend dev? In the use case from the issue summary it makes sense that this is noisy but it also removes it from regular includes.

pdureau’s picture

Assigned: Unassigned » pdureau

In the use case from the issue summary it makes sense

Indeed, in this very specific case, using {% include %} tag (instead of the recommended include() function) with a list of components (that are checked one by one for template existence), we don't want to log errors if we don't find a template.

I guess the original authors of ComponentLoader didn't think about this case, whcih is rarely met.

how do you figure that out as a frontend dev?

I don't have numbers to prove my point but I am not sure most frontend devs are working with a logged account and are watching the Drupal logs ;)

So, I am in favor of merging this change. Can I do it soon or we still need to discuss ?

nod_’s picture

go for it

pdureau’s picture

I will merge soon, i just do a last rebase to make the pipleine run a last time on up-to-date codebase.

  • pdureau committed 791670b5 on main
    fix: #3488260 Stop logging an error when component not found
    
    By: geek-...
pdureau’s picture

Assigned: pdureau » Unassigned
Status: Reviewed & tested by the community » Fixed

Committed 791670b and pushed to main. Thanks!

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.