diff --git a/src/TwigComponent/src/Twig/ComponentTokenParser.php b/src/TwigComponent/src/Twig/ComponentTokenParser.php
index ff072124e41..ec543ee70e2 100644
--- a/src/TwigComponent/src/Twig/ComponentTokenParser.php
+++ b/src/TwigComponent/src/Twig/ComponentTokenParser.php
@@ -12,6 +12,7 @@
namespace Symfony\UX\TwigComponent\Twig;
use Symfony\UX\TwigComponent\BlockStack;
+use Twig\Error\SyntaxError;
use Twig\Node\Expression\AbstractExpression;
use Twig\Node\Expression\ArrayExpression;
use Twig\Node\Expression\ConstantExpression;
@@ -33,6 +34,7 @@ final class ComponentTokenParser extends AbstractTokenParser
public function parse(Token $token): Node
{
$stream = $this->parser->getStream();
+
if (method_exists($this->parser, 'parseExpression')) {
// Since Twig 3.21
$componentName = $this->componentName($this->parser->parseExpression());
@@ -40,6 +42,10 @@ public function parse(Token $token): Node
$componentName = $this->componentName($this->parser->getExpressionParser()->parseExpression());
}
+ if (null === $componentName) {
+ throw new SyntaxError('Could not parse component name.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
+ }
+
[$propsExpression, $only] = $this->parseArguments();
// Write a fake: "extends __parent__" into the "embedded" template.
@@ -80,7 +86,7 @@ public function getTag(): string
return 'component';
}
- private function componentName(AbstractExpression $expression): string
+ private function componentName(AbstractExpression $expression): ?string
{
if ($expression instanceof ConstantExpression) { // using {% component 'name' %}
return $expression->getAttribute('value');
@@ -90,7 +96,7 @@ private function componentName(AbstractExpression $expression): string
return $expression->getAttribute('name');
}
- throw new \LogicException('Could not parse component name.');
+ return null;
}
/**
diff --git a/src/TwigComponent/tests/Integration/Twig/ComponentParserTest.php b/src/TwigComponent/tests/Integration/Twig/ComponentParserTest.php
index 476ee4f24df..c5799440a13 100644
--- a/src/TwigComponent/tests/Integration/Twig/ComponentParserTest.php
+++ b/src/TwigComponent/tests/Integration/Twig/ComponentParserTest.php
@@ -13,6 +13,7 @@
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Twig\Environment;
+use Twig\Error\SyntaxError;
use Twig\Loader\ArrayLoader;
use Twig\TemplateWrapper;
@@ -28,12 +29,12 @@ final class ComponentParserTest extends KernelTestCase
*/
public function testAcceptTwigComponentTagWithValidComponentName(string $name): void
{
- $environment = self::createEnvironment();
+ $environment = $this->createEnvironment();
$source = str_replace('XXX', $name, "{% component 'XXX' %}{% endcomponent %}");
$template = $environment->createTemplate($source);
- self::assertInstanceOf(TemplateWrapper::class, $template);
+ $this->assertInstanceOf(TemplateWrapper::class, $template);
}
/**
@@ -41,12 +42,12 @@ public function testAcceptTwigComponentTagWithValidComponentName(string $name):
*/
public function testAcceptHtmlComponentTagWithValidComponentName(string $name): void
{
- $environment = self::createEnvironment();
+ $environment = $this->createEnvironment();
$source = \sprintf('', $name, $name);
$template = $environment->createTemplate($source);
- self::assertInstanceOf(TemplateWrapper::class, $template);
+ $this->assertInstanceOf(TemplateWrapper::class, $template);
}
/**
@@ -54,12 +55,24 @@ public function testAcceptHtmlComponentTagWithValidComponentName(string $name):
*/
public function testAcceptHtmlSelfClosingComponentTagWithValidComponentName(string $name): void
{
- $environment = self::createEnvironment();
+ $environment = $this->createEnvironment();
$source = \sprintf('', $name);
$template = $environment->createTemplate($source);
- self::assertInstanceOf(TemplateWrapper::class, $template);
+ $this->assertInstanceOf(TemplateWrapper::class, $template);
+ }
+
+ public function testItThrowsWhenComponentNameCannotBeParsed(): void
+ {
+ $environment = $this->createEnvironment();
+ $source = '{% component [] %}{% endcomponent %}';
+
+ $this->expectException(SyntaxError::class);
+ $this->expectExceptionMessage('Could not parse component name in "foo.html.twig');
+ $this->expectExceptionMessage(')" at line 1.');
+
+ $environment->createTemplate($source, 'foo.html.twig');
}
public static function provideValidComponentNames(): iterable