Skip to content

Commit 0cf3a6d

Browse files
committed
minor symfony#2729 [Twig] Improve Parser exceptions (minor) (smnandre)
This PR was merged into the 2.x branch. Discussion ---------- [Twig] Improve Parser exceptions (minor) Improves Parser exception Throw a SyntaxError instead of a LogicError in ComponentParser (following Twig #4601 : twigphp/Twig#4601) Commits ------- 55f8d64 [Twig] Improves Parser exception
2 parents af1fea9 + 55f8d64 commit 0cf3a6d

File tree

2 files changed

+27
-8
lines changed

2 files changed

+27
-8
lines changed

src/TwigComponent/src/Twig/ComponentTokenParser.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\UX\TwigComponent\Twig;
1313

1414
use Symfony\UX\TwigComponent\BlockStack;
15+
use Twig\Error\SyntaxError;
1516
use Twig\Node\Expression\AbstractExpression;
1617
use Twig\Node\Expression\ArrayExpression;
1718
use Twig\Node\Expression\ConstantExpression;
@@ -33,13 +34,18 @@ final class ComponentTokenParser extends AbstractTokenParser
3334
public function parse(Token $token): Node
3435
{
3536
$stream = $this->parser->getStream();
37+
3638
if (method_exists($this->parser, 'parseExpression')) {
3739
// Since Twig 3.21
3840
$componentName = $this->componentName($this->parser->parseExpression());
3941
} else {
4042
$componentName = $this->componentName($this->parser->getExpressionParser()->parseExpression());
4143
}
4244

45+
if (null === $componentName) {
46+
throw new SyntaxError('Could not parse component name.', $stream->getCurrent()->getLine(), $stream->getSourceContext());
47+
}
48+
4349
[$propsExpression, $only] = $this->parseArguments();
4450

4551
// Write a fake: "extends __parent__" into the "embedded" template.
@@ -80,7 +86,7 @@ public function getTag(): string
8086
return 'component';
8187
}
8288

83-
private function componentName(AbstractExpression $expression): string
89+
private function componentName(AbstractExpression $expression): ?string
8490
{
8591
if ($expression instanceof ConstantExpression) { // using {% component 'name' %}
8692
return $expression->getAttribute('value');
@@ -90,7 +96,7 @@ private function componentName(AbstractExpression $expression): string
9096
return $expression->getAttribute('name');
9197
}
9298

93-
throw new \LogicException('Could not parse component name.');
99+
return null;
94100
}
95101

96102
/**

src/TwigComponent/tests/Integration/Twig/ComponentParserTest.php

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
1515
use Twig\Environment;
16+
use Twig\Error\SyntaxError;
1617
use Twig\Loader\ArrayLoader;
1718
use Twig\TemplateWrapper;
1819

@@ -28,38 +29,50 @@ final class ComponentParserTest extends KernelTestCase
2829
*/
2930
public function testAcceptTwigComponentTagWithValidComponentName(string $name): void
3031
{
31-
$environment = self::createEnvironment();
32+
$environment = $this->createEnvironment();
3233
$source = str_replace('XXX', $name, "{% component 'XXX' %}{% endcomponent %}");
3334

3435
$template = $environment->createTemplate($source);
3536

36-
self::assertInstanceOf(TemplateWrapper::class, $template);
37+
$this->assertInstanceOf(TemplateWrapper::class, $template);
3738
}
3839

3940
/**
4041
* @dataProvider provideValidComponentNames
4142
*/
4243
public function testAcceptHtmlComponentTagWithValidComponentName(string $name): void
4344
{
44-
$environment = self::createEnvironment();
45+
$environment = $this->createEnvironment();
4546
$source = \sprintf('<twig:%s></twig:%s>', $name, $name);
4647

4748
$template = $environment->createTemplate($source);
4849

49-
self::assertInstanceOf(TemplateWrapper::class, $template);
50+
$this->assertInstanceOf(TemplateWrapper::class, $template);
5051
}
5152

5253
/**
5354
* @dataProvider provideValidComponentNames
5455
*/
5556
public function testAcceptHtmlSelfClosingComponentTagWithValidComponentName(string $name): void
5657
{
57-
$environment = self::createEnvironment();
58+
$environment = $this->createEnvironment();
5859
$source = \sprintf('<twig:%s />', $name);
5960

6061
$template = $environment->createTemplate($source);
6162

62-
self::assertInstanceOf(TemplateWrapper::class, $template);
63+
$this->assertInstanceOf(TemplateWrapper::class, $template);
64+
}
65+
66+
public function testItThrowsWhenComponentNameCannotBeParsed(): void
67+
{
68+
$environment = $this->createEnvironment();
69+
$source = '{% component [] %}{% endcomponent %}';
70+
71+
$this->expectException(SyntaxError::class);
72+
$this->expectExceptionMessage('Could not parse component name in "foo.html.twig');
73+
$this->expectExceptionMessage(')" at line 1.');
74+
75+
$environment->createTemplate($source, 'foo.html.twig');
6376
}
6477

6578
public static function provideValidComponentNames(): iterable

0 commit comments

Comments
 (0)