diff --git a/CHANGELOG.md b/CHANGELOG.md index b52593d..f071043 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ Latest ------ ### Changes +* [#63](https://github.com/cleverage/cache-process-bundle/issues/63) The bundle throws exceptions implementing `ProcessExceptionInterface` of the process bundle instead of raw SPL exceptions (as [cleverage/process-bundle#317](https://github.com/cleverage/process-bundle/issues/317)): new `Exception\UnexpectedValueException`, extending the SPL exceptions thrown before (same messages, the existing `catch` keep working). `MissingAdapterException` implements `ProcessExceptionInterface`. Add tests. * [#61](https://github.com/cleverage/cache-process-bundle/issues/61) Composer: require PHP `^8.2` instead of `>=8.2` (PHP 9 is no longer accepted before being tested), remove the authorization of the `symfony/flex` plugin, which is not required (the CI installs it globally), as [cleverage/process-bundle#319](https://github.com/cleverage/process-bundle/issues/319). * [#56](https://github.com/cleverage/cache-process-bundle/issues/56) Define the public API (Symfony BC promise, as [cleverage/process-bundle#279](https://github.com/cleverage/process-bundle/issues/279)): `GetTask`, `SetTask`, `AdapterRegistry` and `CleverAgeCacheProcessBundle` are marked `@final since 2.3`, they will be `final` in 3.0: extending them triggers a deprecation with the Symfony `DebugClassLoader`. `AbstractCacheTask`, `Adapter` (extended by the applications) and `MissingAdapterException` stay open. `CleverAgeCacheProcessExtension` and `RegisterAdaptersPass` are marked `@internal`. * [#55](https://github.com/cleverage/cache-process-bundle/issues/55) `CleverAgeCacheProcessExtension::findServices()` loads the service definition files with a glob pattern instead of a `Finder` (same files, as [cleverage/process-bundle#271](https://github.com/cleverage/process-bundle/issues/271)), `symfony/finder` is no longer required. Add tests. diff --git a/src/Exception/MissingAdapterException.php b/src/Exception/MissingAdapterException.php index 2354fec..56bdd58 100644 --- a/src/Exception/MissingAdapterException.php +++ b/src/Exception/MissingAdapterException.php @@ -13,9 +13,11 @@ namespace CleverAge\CacheProcessBundle\Exception; +use CleverAge\ProcessBundle\Exception\ProcessExceptionInterface; + /** * Exception thrown when trying to fetch a missing Cache Adapter. */ -class MissingAdapterException extends \Exception +class MissingAdapterException extends \Exception implements ProcessExceptionInterface { } diff --git a/src/Exception/UnexpectedValueException.php b/src/Exception/UnexpectedValueException.php new file mode 100644 index 0000000..5841309 --- /dev/null +++ b/src/Exception/UnexpectedValueException.php @@ -0,0 +1,23 @@ +adapters[$code] = $adapter; $this->serviceIds[$code] = $serviceId; @@ -104,10 +105,10 @@ public function getAdapter(string $code): AdapterInterface $adapter = $this->locator->get($code); if (!$adapter instanceof AdapterInterface) { - throw new \UnexpectedValueException(\sprintf('The service of the cache adapter "%s" must implement "%s".', $code, AdapterInterface::class)); + throw new UnexpectedValueException(\sprintf('The service of the cache adapter "%s" must implement "%s".', $code, AdapterInterface::class)); } if ($code !== $adapter->getCode()) { - throw new \UnexpectedValueException(\sprintf('The cache adapter "%s" is registered with the code "%s" but its getCode() method returns "%s": both must be the same.', $adapter::class, $code, $adapter->getCode())); + throw new UnexpectedValueException(\sprintf('The cache adapter "%s" is registered with the code "%s" but its getCode() method returns "%s": both must be the same.', $adapter::class, $code, $adapter->getCode())); } return $this->adapters[$code] = $adapter; diff --git a/src/Task/AbstractCacheTask.php b/src/Task/AbstractCacheTask.php index 8ef3a2b..db36611 100644 --- a/src/Task/AbstractCacheTask.php +++ b/src/Task/AbstractCacheTask.php @@ -13,6 +13,7 @@ namespace CleverAge\CacheProcessBundle\Task; +use CleverAge\CacheProcessBundle\Exception\UnexpectedValueException; use CleverAge\CacheProcessBundle\Registry\AdapterRegistry; use CleverAge\ProcessBundle\Model\AbstractConfigurableTask; use CleverAge\ProcessBundle\Model\ProcessState; @@ -67,7 +68,7 @@ protected function getMergedOptions(ProcessState $state): array $input = $state->getInput() ?: []; if (!\is_array($input)) { - throw new \UnexpectedValueException(\sprintf('%s expects an array or null input, %s given', (new \ReflectionClass($this))->getShortName(), get_debug_type($input))); + throw new UnexpectedValueException(\sprintf('%s expects an array or null input, %s given', (new \ReflectionClass($this))->getShortName(), get_debug_type($input))); } $resolver = new OptionsResolver(); diff --git a/src/Task/GetTask.php b/src/Task/GetTask.php index 9eab113..b99ffde 100644 --- a/src/Task/GetTask.php +++ b/src/Task/GetTask.php @@ -13,6 +13,7 @@ namespace CleverAge\CacheProcessBundle\Task; +use CleverAge\CacheProcessBundle\Exception\UnexpectedValueException; use CleverAge\ProcessBundle\Model\ProcessState; use Symfony\Component\OptionsResolver\Exception\AccessException; use Symfony\Component\OptionsResolver\Exception\UndefinedOptionsException; @@ -57,7 +58,7 @@ public function execute(ProcessState $state): void return; } if (self::ON_MISS_FAIL === $mergedOptions['on_miss']) { - throw new \UnexpectedValueException("Cache item {$mergedOptions['key']} is missing from adapter {$mergedOptions['adapter']}"); + throw new UnexpectedValueException("Cache item {$mergedOptions['key']} is missing from adapter {$mergedOptions['adapter']}"); } } diff --git a/tests/Exception/SplExceptionsTest.php b/tests/Exception/SplExceptionsTest.php new file mode 100644 index 0000000..d37f29e --- /dev/null +++ b/tests/Exception/SplExceptionsTest.php @@ -0,0 +1,57 @@ +, class-string<\Throwable>}> + */ + public static function provideExceptions(): iterable + { + yield 'UnexpectedValueException' => [UnexpectedValueException::class, \UnexpectedValueException::class]; + } + + public function testExceptionsOfTheBundleImplementTheInterface(): void + { + self::assertInstanceOf(ProcessExceptionInterface::class, new MissingAdapterException('message')); + } + + /** + * @param class-string<\Throwable> $class + * @param class-string<\Throwable> $splClass + */ + #[DataProvider('provideExceptions')] + public function testExtendsTheSplExceptionAndImplementsTheInterface(string $class, string $splClass): void + { + $exception = new $class('message', 12); + + self::assertInstanceOf($splClass, $exception); + self::assertInstanceOf(ProcessExceptionInterface::class, $exception); + self::assertSame(['message', 12], [$exception->getMessage(), $exception->getCode()]); + } +}