Just a minor problem...
mymodule.twig.foobar:
class: Drupal\mymodule\Template\TwigFoobarExtension
tags:
- { name: twig.extension }
If you create a tagged service, e.g. for a twig extension, and the entered namespace can't be resolved/file can't be found, you get a misleading exception:
exception 'Symfony\Component\DependencyInjection\Exception\LogicException' with message 'Service 'mymodule.twig.foobar' for consumer 'twig' does not [error]
implement Twig_ExtensionInterface.
if (!is_subclass_of($handler->getClass(), $interface)) {
throw new LogicException("Service '$id' for consumer '$consumer_id' does not implement $interface.");
}
My suggestion:
Service '$id' for consumer '$consumer_id' does not implement $interface, or its namespace cannot be resolved.
This might save some time for anyone else.
Comments
Comment #2
cilefen commentedIf the exception is in Symfony it must be fixed there.
Comment #3
seppelM commentedsee line 130 of Drupal/Core/DependencyInjecetion/Compiler/TaggedHandlersPass (https://api.drupal.org/api/drupal/core!lib!Drupal!Core!DependencyInjecti...).
It's not part of the vendor components.
Comment #4
cilefen commentedSorry, you are right. I was confused by the exception's namespace, Symfony\Component\DependencyInjection\Exception\LogicException.
Comment #5
cilefen commentedComment #8
erickatbattle commentedHello guys, I am working on trying to extend the twig function from a custom module and I am also getting the same issue mentioned above, is this something still being worked on?
Or would anybody know a solution.
I am getting the following error:
My services file looks like this:
Thanks
Comment #9
cilefen commentedThis issue is about a misleading error when the namespace can't be found. In your case, does Drupal\bml_site\Twig\BMLSiteExtension exist and does it implement Twig_ExtensionInterface or more likely, extend \Twig_Extension?
Comment #10
steve-spa-tech commentedJust a quick note, when this was just occurring for me I found that the src file name is case sensitive
i.e. my class def is "class Images extends \Twig_Extension", with a filename of "images.php" it would fail compilation, but "Images.php" would work. (probably not related to the core issue but might help newcomers like me to get some progress).
Steve.
Comment #11
dawehnerMaybe something which tells that either the class or the namespace is wrong would be IMHO more concrete. The current proposed error message seems to be really cryptic, at least for me.
Comment #12
pounardThere's a real bug here, most Symfony's compiler class will manually resolve class names before using it, for example you can see it there: https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Eve...
Drupal never does this, and as soon as you rely upon parameters for class names, Drupal will go into havoc, and this is a seriously blocking issue for contrib.
I am preparing a complete explicative bug report for this and a preliminary proof a concept patch, will link it here as soon as it's done.
Comment #13
pounardAnd done! https://www.drupal.org/node/2832018
Comment #16
lorenzs commentedAs I lost some time on this I'd suggest putting it in while we wait for #2832018 to be completed. Tested.
Comment #17
xjmI agree with @dawehner in #11; the current exception message doesn't go far enough to explain the problem. I agree with hotfixing this while #2832018: Compiler passes don't manually resolve class names of definition before using it is underway to provide better DX and debugging, and I think we could still backport it since exception messages are not translated and we're not changing what exceptions are thrown or where, but I wouldn't know what to do with "its namespace cannot be resolved". So let's add more detail that the class or namespace could be incorrect...
But actually, we should probably be throwing a different exception message earlier. Is this happening if
$handleror$handler->getClass()are empty? If so, we could throw a different exception in that case rather than relying on an unclear "or".Comment #19
berenddeboer commentedJust got hit with this too. Drupal 8 is already extremely hard to use, why can't somebody just add this easy patch?
Comment #20
cilefen commentedThe reason is that the feedback in #17 hasn’t been seen to. Please upload a patch.
Comment #21
dawehnerHere is a test coverage, anyone wants to try to implement it?
Comment #28
marcvangendI would love to see this fixed.
The error message "consumer X does not implement Y" is so specific that it can completely get you off on the wrong foot. If your problem isn't exactly that, it only makes debugging more difficult.
Also, I'm cringing at the fact that this has been tagged as "Quick fix" for 6 years. This is a case of "perfect is the enemy of good". The patch from #5 would have been incredibly helpful. I'm marking this RTBC: let's commit #5 and do the gold-plating in another issue.
Comment #29
longwave@dawehner provided a failing test in #21, this needs to be combined with the patch in #5 to solve this issue.
Comment #31
pradhumanjain2311 commentedAddressed Comment #29.
Comment #32
pradhumanjain2311 commentedFix CS ERRORS.
Comment #33
smustgrave commentedThe last patch doesn't pass commit checks, could you make sure to run
./core/scripts/dev/commit-code-check.shbefore uploading a patch to make sure there are no issues with code formatting. see https://www.drupal.org/docs/develop/development-tools/running-core-devel...Fixed deprecation issu.e
Comment #35
smustgrave commentedFixed up test case.
Comment #36
longwaveThe test from #21 was more specific; it should be possible to know which of the error cases is the actual issue by providing a different message for each, instead of leaving it to the developer to work out.
Comment #37
smustgrave commentedUpdated for message from #21.
Comment #38
smustgrave commentednot sure what happened in #37
Comment #40
smustgrave commentedRandom failure
Comment #41
stefanos.petrakisIMO the change in the exception message from #37 to #38
- does not implement $interface, or its namespace cannot be resolved.+ does not have an existing class $interface.is restoring some confusion to the dev/reader, i.e. it does little to inform that the provided
class:for the collected service does not exist. The$interfacevariable will be generated based on the service collector's definition and not the collected service.Even more, the actual change in code could focus explicitly on this case, e.g.:
That would mean a small change in the first one of the new tests to capture the new exception for non-existing classes.
And a small change in the second test, if we stick to the original exception message (
Service '$id' for consumer '$consumer_id' does not implement $interface.