Tagged services - misleading exception

Created on 19 January 2016, about 9 years ago
Updated 10 April 2023, almost 2 years ago

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.

πŸ› Bug report
Status

Needs work

Version

10.1 ✨

Component
BaseΒ  β†’

Last updated about 15 hours ago

Created by

πŸ‡©πŸ‡ͺGermany seppelM

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

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

    Updated for message from #21.

  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    not sure what happened in #37

  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    Random failure

  • Status changed to Needs work almost 2 years ago
  • πŸ‡¨πŸ‡­Switzerland stefanos.petrakis@gmail.com Biel, Switzerland

    IMO 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 $interface variable 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.:

    +++ b/core/lib/Drupal/Core/DependencyInjection/Compiler/TaggedHandl
    ersPass.php
    @@ -178,6 +178,9 @@ protected function processServiceCollectorPass(
    array $pass, $consumer_id, Contai
         foreach ($this->tagCache[$tag] ?? [] as $id => $attributes) {
           // Validate the interface.
           $handler = $container->getDefinition($id);
    +      if (class_exists($handler->getClass()) === FALSE) {
    +        throw new LogicException("Service '$id' for consumer '$con
    sumer_id' does not have a corresponding existing class " . $handler
    ->getClass());
    +      }
           if (!is_subclass_of($handler->getClass(), $interface)) {
             throw new LogicException("Service '$id' for consumer '$con
    sumer_id' does not implement $interface.");
           }
    

    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.

Production build 0.71.5 2024