Skip to content

Commit

Permalink
Improve the error handling while failure on an expression parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
jakubtobiasz committed Apr 19, 2024
1 parent a77600e commit f296faa
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 4 deletions.
5 changes: 3 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
}
],
"require": {
"laminas/laminas-stdlib": "^3.18",
"php": "^8.1",
"laminas/laminas-stdlib": "^3.18",
"symfony/config": "^5.4 || ^6.0",
"symfony/dependency-injection": "^5.4 || ^6.0",
"symfony/expression-language": "^5.4 || ^6.0",
Expand Down Expand Up @@ -58,7 +58,8 @@
}
},
"replace": {
"sylius/twig-event": "self.version"
"sylius/twig-event": "self.version",
"sylius/twig-hooks": "self.version"
},
"config": {
"allow-plugins": {
Expand Down
18 changes: 16 additions & 2 deletions src/TwigHooks/src/Provider/ComponentDataProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace Sylius\TwigHooks\Provider;

use Sylius\TwigHooks\Hookable\AbstractHookable;
use Sylius\TwigHooks\Provider\Exception\InvalidExpressionException;
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;

final class ComponentDataProvider implements DataProviderInterface
Expand All @@ -16,9 +17,22 @@ public function __construct (

public function provide(AbstractHookable $hookable, array $hookData): array
{
return $this->mapArrayRecursively(function (mixed $value) use ($hookData): mixed {
return $this->mapArrayRecursively(function (mixed $value) use ($hookData, $hookable): mixed {
if (is_string($value) && str_starts_with($value, '@=')) {
return $this->expressionLanguage->evaluate(substr($value, 2), $hookData);
try {
return $this->expressionLanguage->evaluate(substr($value, 2), $hookData);
} catch (\Throwable $e) {
throw new InvalidExpressionException(
sprintf(
'Failed to evaluate the "%s" expression while rendering the "%s" hookable in the "%s" hook. Error: %s".',
$value,
$hookable->getName(),
$hookable->getHookName(),
$e->getMessage(),
),
previous: $e,
);
}
}

return $value;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

declare(strict_types=1);

namespace Sylius\TwigHooks\Provider\Exception;

class InvalidExpressionException extends \Exception
{
}
15 changes: 15 additions & 0 deletions src/TwigHooks/tests/Unit/Provider/ComponentDataProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use PHPUnit\Framework\TestCase;
use Sylius\TwigHooks\Provider\ComponentDataProvider;
use Sylius\TwigHooks\Provider\DataProviderInterface;
use Sylius\TwigHooks\Provider\Exception\InvalidExpressionException;
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
use Tests\Sylius\TwigHooks\Utils\MotherObject\BaseHookableMotherObject;

Expand Down Expand Up @@ -41,6 +42,20 @@ public function testItPassesTemplateLevelDataToExpressionLanguage(): void
$this->assertSame(['some_key' => 'data'], $dataProvider->provide($hookable, ['some' => 'data', 'another' => 'data']));
}

public function testItThrowsCustomExceptionWhenEvaluatingAnExpressionFails(): void
{
$hookable = BaseHookableMotherObject::withData(['some_key' => '@=some.nonExistingMethod()']);

$dataProvider = $this->createTestSubject();

$this->expectException(InvalidExpressionException::class);
$this->expectExceptionMessage(
'Failed to evaluate the "@=some.nonExistingMethod()" expression while rendering the "some_name" hookable in the "some_hook" hook. Error: Unable to call method "nonExistingMethod" of non-object "some".".',
);

$dataProvider->provide($hookable, ['some' => 'data', 'another' => 'data']);
}

private function createTestSubject(): DataProviderInterface
{
return new ComponentDataProvider(
Expand Down

0 comments on commit f296faa

Please sign in to comment.