diff --git a/src/TwigHooks/src/Hookable/Renderer/Exception/HookRenderException.php b/src/TwigHooks/src/Hookable/Renderer/Exception/HookRenderException.php index a67c54c1..ea858749 100644 --- a/src/TwigHooks/src/Hookable/Renderer/Exception/HookRenderException.php +++ b/src/TwigHooks/src/Hookable/Renderer/Exception/HookRenderException.php @@ -13,8 +13,22 @@ namespace Sylius\TwigHooks\Hookable\Renderer\Exception; +use Twig\Error\Error; use Twig\Error\RuntimeError; +use Twig\Source; class HookRenderException extends RuntimeError { + public function __construct(string $message, ?int $lineno = null, ?Source $source = null, ?\Throwable $previous = null) + { + $lineno ??= $previous?->getLine() ?? -1; + $source ??= $previous instanceof Error ? $previous->getSourceContext() : null; + + parent::__construct( + $message, + $lineno, + $source, + $previous, + ); + } } diff --git a/src/TwigHooks/src/Hookable/Renderer/HookableTemplateRenderer.php b/src/TwigHooks/src/Hookable/Renderer/HookableTemplateRenderer.php index d7745d35..adf8f6ae 100644 --- a/src/TwigHooks/src/Hookable/Renderer/HookableTemplateRenderer.php +++ b/src/TwigHooks/src/Hookable/Renderer/HookableTemplateRenderer.php @@ -42,12 +42,15 @@ public function render(AbstractHookable $hookable, HookableMetadata $metadata): return $this->twig->render($hookable->template, [ HooksRuntime::HOOKABLE_METADATA => $metadata, ]); + } catch (HookRenderException $exception) { + throw $exception; } catch (\Throwable $exception) { throw new HookRenderException( sprintf( - 'An error occurred during rendering the "%s" hook in the "%s" hookable', + 'An error occurred during rendering the "%s" hook in the "%s" hookable. %s', $hookable->name, $hookable->hookName, + $exception->getMessage(), ), previous: $exception, ); diff --git a/src/TwigHooks/tests/Unit/Hookable/Renderer/HookableTemplateRendererTest.php b/src/TwigHooks/tests/Unit/Hookable/Renderer/HookableTemplateRendererTest.php index 225c763d..a1f56d50 100644 --- a/src/TwigHooks/tests/Unit/Hookable/Renderer/HookableTemplateRendererTest.php +++ b/src/TwigHooks/tests/Unit/Hookable/Renderer/HookableTemplateRendererTest.php @@ -16,10 +16,12 @@ use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Sylius\TwigHooks\Hookable\Metadata\HookableMetadata; +use Sylius\TwigHooks\Hookable\Renderer\Exception\HookRenderException; use Sylius\TwigHooks\Hookable\Renderer\HookableTemplateRenderer; use Tests\Sylius\TwigHooks\Utils\MotherObject\HookableComponentMotherObject; use Tests\Sylius\TwigHooks\Utils\MotherObject\HookableTemplateMotherObject; use Twig\Environment as Twig; +use Twig\Error\Error; final class HookableTemplateRendererTest extends TestCase { @@ -65,6 +67,22 @@ public function testItRendersHookableTemplate(): void $this->assertSame('some-rendered-template', $renderedTemplate); } + public function testItThrowsAnExceptionWhenTwigThrowsAnError(): void + { + $metadata = $this->createMock(HookableMetadata::class); + + $this->twig->expects($this->once())->method('render')->with('some-template', [ + 'hookable_metadata' => $metadata, + ])->willThrowException(new Error('Unable to find the template.')); + + $hookable = HookableTemplateMotherObject::withTarget('some-template'); + + $this->expectException(HookRenderException::class); + $this->expectExceptionMessage('An error occurred during rendering the "some_name" hook in the "some_hook" hookable. Unable to find the template at line 76.'); + + $this->getTestSubject()->render($hookable, $metadata); + } + private function getTestSubject(): HookableTemplateRenderer { return new HookableTemplateRenderer($this->twig);