You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
minor #60415 [TwigBundle] Improve error when autoconfiguring a class with both ExtensionInterface and Twig callable attribute (GromNaN)
This PR was merged into the 7.3 branch.
Discussion
----------
[TwigBundle] Improve error when autoconfiguring a class with both `ExtensionInterface` and Twig callable attribute
| Q | A
| ------------- | ---
| Branch? | 7.3
| Bug fix? | no
| New feature? | no
| Deprecations? | no
| Issues | -
| License | MIT
Reported by Javier:
> I'm updating Twig extensions to use the `#[AsTwig...]` attributes. I removed the `getFunctions()` method and had this:
> ```
> class FooExtension extends AbstractExtension
> {
> #[AsTwigFunction('name_of_function')]
> public function foo(): string
> {
> // ...
> }
> }
> ```
> Then I saw this exception: `Unable to register extension "App\Twig\FooExtension" as it is already registered.`
> My error is that I forgot to remove extends `AbstractExtension`
But I think that Symfony's error exception should be more helpful. A quick example of something that could've helped me: *"When using the AsTwigFunction attribute, your Twig extension cannot extend AbstractExtension"*
The ExtensionSet exception is thrown because the same an extension is registered twice:
1. It has the `twig.extension` tag autoconfigured because it implements `Twig\Extension\ExtensionInterface`
2. An `AttributeExtension` is registered for this class because it as one of the extension attributes (since #52748)
Previous exception when `twig` service is instanciated:
> LogicException : Unable to register extension "Symfony\Bundle\TwigBundle\Tests\Functional\InvalidExtensionWithAttributes" as it is already registered.
New exception during container compilation:
> Symfony\Component\DependencyInjection\Exception\LogicException : The class "Symfony\Bundle\TwigBundle\Tests\Functional\InvalidExtensionWithAttributes" cannot both extend "Twig\Extension\AbstractExtension" and use the "#[Twig\Attribute\AsTwigFilter]" attribute on method "funFilter()", choose one or the other.
Checking `AbstractExtension` makes the error message more specific to the code, as most extensions extend this class and doesn't implement the interface directly.
Commits
-------
752b41d [TwigBundle] Improve error when autoconfiguring a class with both ExtensionInterface and Twig callable attribute
if ($class->implementsInterface(ExtensionInterface::class)) {
41
+
if ($class->isSubclassOf(AbstractExtension::class)) {
42
+
thrownewLogicException(\sprintf('The class "%s" cannot extend "%s" and use the "#[%s]" attribute on method "%s()", choose one or the other.', $class->name, AbstractExtension::class, $attribute::class, $reflector->name));
43
+
}
44
+
thrownewLogicException(\sprintf('The class "%s" cannot implement "%s" and use the "#[%s]" attribute on method "%s()", choose one or the other.', $class->name, ExtensionInterface::class, $attribute::class, $reflector->name));
45
+
}
46
+
36
47
$definition->addTag(self::TAG);
37
48
38
49
// The service must be tagged as a runtime to call non-static methods
$this->expectExceptionMessage('The class "Symfony\Bundle\TwigBundle\Tests\Functional\InvalidExtensionWithAttributes" cannot extend "Twig\Extension\AbstractExtension" and use the "#[Twig\Attribute\AsTwigFilter]" attribute on method "funFilter()", choose one or the other.');
89
+
90
+
$kernel->boot();
91
+
}
92
+
93
+
76
94
/**
77
95
* @before
78
96
* @after
79
97
*/
98
+
#[Before, After]
80
99
protectedfunctiondeleteTempDir()
81
100
{
82
101
if (file_exists($dir = sys_get_temp_dir().'/'.Kernel::VERSION.'/AttributeExtension')) {
@@ -85,6 +104,24 @@ protected function deleteTempDir()
0 commit comments