diff --git a/README.md b/README.md index 5017e38..37f4934 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ $factory = \Keepsuit\Liquid\EnvironmentFactory::new() // enable strict variables mode ->setStrictVariables() // rethrow exceptions instead of rendering them - ->setRethrowExceptions() + ->setRethrowErrors() // set filesystem used to load templates ->setFilesystem(new \Keepsuit\Liquid\FileSystems\LocalFileSystem(__DIR__ . '/views')); ``` diff --git a/src/Contracts/LiquidErrorHandler.php b/src/Contracts/LiquidErrorHandler.php new file mode 100644 index 0000000..d66ff04 --- /dev/null +++ b/src/Contracts/LiquidErrorHandler.php @@ -0,0 +1,14 @@ +tagRegistry = $tagRegistry ?? TagRegistry::default(); $this->filterRegistry = $filterRegistry ?? FilterRegistry::default(); $this->fileSystem = $fileSystem ?? new BlankFileSystem; + $this->errorHandler = $errorHandler ?? new DefaultErrorHandler; $this->defaultResourceLimits = $defaultResourceLimits ?? new ResourceLimits; $this->defaultRenderContextOptions = $defaultRenderContextOptions ?? new RenderContextOptions; } diff --git a/src/EnvironmentFactory.php b/src/EnvironmentFactory.php index 206683c..fff1627 100644 --- a/src/EnvironmentFactory.php +++ b/src/EnvironmentFactory.php @@ -2,7 +2,9 @@ namespace Keepsuit\Liquid; +use Keepsuit\Liquid\Contracts\LiquidErrorHandler; use Keepsuit\Liquid\Contracts\LiquidFileSystem; +use Keepsuit\Liquid\ErrorHandlers\DefaultErrorHandler; use Keepsuit\Liquid\FileSystems\BlankFileSystem; use Keepsuit\Liquid\Filters\FiltersProvider; use Keepsuit\Liquid\Render\RenderContextOptions; @@ -18,6 +20,8 @@ final class EnvironmentFactory protected LiquidFileSystem $fileSystem; + protected LiquidErrorHandler $errorHandler; + protected ResourceLimits $resourceLimits; protected RenderContextOptions $defaultRenderContextOptions; @@ -29,6 +33,7 @@ public function __construct() $this->tagRegistry = TagRegistry::default(); $this->filterRegistry = FilterRegistry::default(); $this->fileSystem = new BlankFileSystem; + $this->errorHandler = new DefaultErrorHandler; $this->resourceLimits = new ResourceLimits; $this->defaultRenderContextOptions = new RenderContextOptions; } @@ -59,6 +64,13 @@ public function setFilesystem(LiquidFileSystem $fileSystem): EnvironmentFactory return $this; } + public function setErrorHandler(LiquidErrorHandler $errorHandler): EnvironmentFactory + { + $this->errorHandler = $errorHandler; + + return $this; + } + public function setResourceLimits(ResourceLimits $resourceLimits): EnvironmentFactory { $this->resourceLimits = $resourceLimits; @@ -73,12 +85,12 @@ public function setProfile(bool $profile = true): EnvironmentFactory return $this; } - public function setRethrowExceptions(bool $rethrowExceptions = true): EnvironmentFactory + public function setRethrowErrors(bool $rethrowErrors = true): EnvironmentFactory { $this->defaultRenderContextOptions = new RenderContextOptions( strictVariables: $this->defaultRenderContextOptions->strictVariables, strictFilters: $this->defaultRenderContextOptions->strictFilters, - rethrowExceptions: $rethrowExceptions, + rethrowErrors: $rethrowErrors, ); return $this; @@ -89,7 +101,7 @@ public function setStrictVariables(bool $strictVariables = true): EnvironmentFac $this->defaultRenderContextOptions = new RenderContextOptions( strictVariables: $strictVariables, strictFilters: $this->defaultRenderContextOptions->strictFilters, - rethrowExceptions: $this->defaultRenderContextOptions->rethrowExceptions, + rethrowErrors: $this->defaultRenderContextOptions->rethrowErrors, ); return $this; @@ -100,7 +112,7 @@ public function setStrictFilters(bool $strictFilters = true): EnvironmentFactory $this->defaultRenderContextOptions = new RenderContextOptions( strictVariables: $this->defaultRenderContextOptions->strictVariables, strictFilters: $strictFilters, - rethrowExceptions: $this->defaultRenderContextOptions->rethrowExceptions, + rethrowErrors: $this->defaultRenderContextOptions->rethrowErrors, ); return $this; diff --git a/src/ErrorHandlers/DefaultErrorHandler.php b/src/ErrorHandlers/DefaultErrorHandler.php new file mode 100644 index 0000000..1335061 --- /dev/null +++ b/src/ErrorHandlers/DefaultErrorHandler.php @@ -0,0 +1,14 @@ +toLiquidErrorMessage(); + } +} diff --git a/src/ErrorHandlers/RethrowErrorHandler.php b/src/ErrorHandlers/RethrowErrorHandler.php new file mode 100644 index 0000000..798740c --- /dev/null +++ b/src/ErrorHandlers/RethrowErrorHandler.php @@ -0,0 +1,14 @@ +environment = $environment ?? Environment::default(); $this->resourceLimits = $resourceLimits ?? ResourceLimits::clone($this->environment->defaultResourceLimits); + $this->errorHandler = $this->options->rethrowErrors ? new RethrowErrorHandler : $this->environment->errorHandler; $this->scopes = [[]]; @@ -299,11 +304,7 @@ public function handleError(Throwable $error, ?int $lineNumber = null): string $this->sharedState->errors[] = $error; - if ($this->options->rethrowExceptions) { - throw $error; - } - - return $error->toLiquidErrorMessage(); + return $this->errorHandler->handle($error); } public function getErrors(): array diff --git a/src/Render/RenderContextOptions.php b/src/Render/RenderContextOptions.php index e2b22c7..ccc9d78 100644 --- a/src/Render/RenderContextOptions.php +++ b/src/Render/RenderContextOptions.php @@ -16,6 +16,6 @@ public function __construct( /** * Rethrow exceptions that occur during rendering instead of rendering the error message. */ - public readonly bool $rethrowExceptions = false, + public readonly bool $rethrowErrors = false, ) {} } diff --git a/tests/Integration/Tags/AssignTagTest.php b/tests/Integration/Tags/AssignTagTest.php index 004f103..25e4c59 100644 --- a/tests/Integration/Tags/AssignTagTest.php +++ b/tests/Integration/Tags/AssignTagTest.php @@ -57,11 +57,11 @@ test('assign score exceeding resource limit', function () { $template = parseTemplate('{% assign foo = 42 %}{% assign bar = 23 %}'); - $context = new RenderContext(options: new RenderContextOptions(rethrowExceptions: true), resourceLimits: new ResourceLimits(assignScoreLimit: 1)); + $context = new RenderContext(options: new RenderContextOptions(rethrowErrors: true), resourceLimits: new ResourceLimits(assignScoreLimit: 1)); expect(fn () => $template->render($context))->toThrow(ResourceLimitException::class); expect($context->resourceLimits->reached())->toBeTrue(); - $context = new RenderContext(options: new RenderContextOptions(rethrowExceptions: true), resourceLimits: new ResourceLimits(assignScoreLimit: 2)); + $context = new RenderContext(options: new RenderContextOptions(rethrowErrors: true), resourceLimits: new ResourceLimits(assignScoreLimit: 2)); expect($template->render($context))->toBe(''); expect($context->resourceLimits->reached())->toBeFalse(); expect($context->resourceLimits->getAssignScore())->toBe(2); @@ -69,7 +69,7 @@ test('assign score exceeding resource limit from composite object', function () { $environment = EnvironmentFactory::new() - ->setRethrowExceptions() + ->setRethrowErrors() ->build(); $template = $environment->parseString("{% assign foo = 'aaaa' | split: '' %}"); @@ -104,7 +104,7 @@ function assignScoreOf(mixed $value): int { - $context = new RenderContext(staticData: ['value' => $value], options: new RenderContextOptions(rethrowExceptions: true)); + $context = new RenderContext(staticData: ['value' => $value], options: new RenderContextOptions(rethrowErrors: true)); parseTemplate('{% assign obj = value %}')->render($context); return $context->resourceLimits->getAssignScore(); diff --git a/tests/Integration/Tags/ForTagTest.php b/tests/Integration/Tags/ForTagTest.php index 2cec5d3..1f111f7 100644 --- a/tests/Integration/Tags/ForTagTest.php +++ b/tests/Integration/Tags/ForTagTest.php @@ -366,7 +366,7 @@ }); test('for cleans up registers', function () { - $context = new RenderContext(staticData: ['drop' => new ErrorDrop], options: new RenderContextOptions(rethrowExceptions: true)); + $context = new RenderContext(staticData: ['drop' => new ErrorDrop], options: new RenderContextOptions(rethrowErrors: true)); expect(fn () => parseTemplate('{% for i in (1..2) %}{{ drop.standard_error }}{% endfor %}')->render($context))->toThrow(\Keepsuit\Liquid\Exceptions\StandardException::class); diff --git a/tests/Integration/TemplateTest.php b/tests/Integration/TemplateTest.php index 9af4a17..b066f54 100644 --- a/tests/Integration/TemplateTest.php +++ b/tests/Integration/TemplateTest.php @@ -82,7 +82,7 @@ test('resource limits abort rendering after first error', function () { $template = parseTemplate('{% for a in (1..100) %} foo1 {% endfor %} bar {% for a in (1..100) %} foo2 {% endfor %}'); $context = new RenderContext( - options: new RenderContextOptions(rethrowExceptions: false), + options: new RenderContextOptions(rethrowErrors: false), resourceLimits: new ResourceLimits(renderScoreLimit: 50) ); expect(fn () => $template->render($context))->toThrow(ResourceLimitException::class); @@ -130,7 +130,7 @@ test('undefined variables', function (bool $strict) { $environment = EnvironmentFactory::new() - ->setRethrowExceptions(false) + ->setRethrowErrors(false) ->setStrictVariables($strict) ->build(); @@ -169,7 +169,7 @@ ], options: new RenderContextOptions( strictVariables: $strict, - rethrowExceptions: false, + rethrowErrors: false, ) ); @@ -184,7 +184,7 @@ test('undefined drop method', function (bool $strict) { $environment = EnvironmentFactory::new() - ->setRethrowExceptions(false) + ->setRethrowErrors(false) ->setStrictVariables($strict) ->build(); @@ -211,7 +211,7 @@ test('undefined drop method throw exception', function (bool $strict) { $environment = EnvironmentFactory::new() - ->setRethrowExceptions() + ->setRethrowErrors() ->setStrictVariables($strict) ->build(); @@ -234,7 +234,7 @@ test('undefined filter', function (bool $strict) { $environment = EnvironmentFactory::new() - ->setRethrowExceptions(false) + ->setRethrowErrors(false) ->setStrictFilters($strict) ->build(); @@ -264,7 +264,7 @@ test('undefined filter throw exception', function (bool $strict) { $environment = EnvironmentFactory::new() - ->setRethrowExceptions() + ->setRethrowErrors() ->setStrictFilters($strict) ->build(); diff --git a/tests/Pest.php b/tests/Pest.php index 65df252..e10ecc0 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -55,7 +55,7 @@ function renderTemplate( $environment = $factory ->setFilesystem(new StubFileSystem(partials: $partials)) ->setStrictVariables($strictVariables) - ->setRethrowExceptions(! $renderErrors) + ->setRethrowErrors(! $renderErrors) ->build(); $template = $environment->parseString($template); @@ -86,7 +86,7 @@ function streamTemplate( $environment = $factory ->setFilesystem(new StubFileSystem(partials: $partials)) ->setStrictVariables($strictVariables) - ->setRethrowExceptions(! $renderErrors) + ->setRethrowErrors(! $renderErrors) ->build(); $template = $environment->parseString($template); diff --git a/tests/Unit/EnvironmentFactoryTest.php b/tests/Unit/EnvironmentFactoryTest.php index 3f54eeb..ab9ed3e 100644 --- a/tests/Unit/EnvironmentFactoryTest.php +++ b/tests/Unit/EnvironmentFactoryTest.php @@ -25,13 +25,13 @@ test('default render options settings', function () { $environment = EnvironmentFactory::new() - ->setRethrowExceptions() + ->setRethrowErrors() ->setStrictVariables() ->setStrictFilters() ->build(); expect($environment) - ->defaultRenderContextOptions->rethrowExceptions->toBeTrue() + ->defaultRenderContextOptions->rethrowErrors->toBeTrue() ->defaultRenderContextOptions->strictVariables->toBeTrue() ->defaultRenderContextOptions->strictFilters->toBeTrue(); });