From aa758bfb7fafa7c62c11340974bd44cfd0555750 Mon Sep 17 00:00:00 2001 From: Joel Wurtz Date: Mon, 6 May 2024 00:11:17 +0200 Subject: [PATCH] feat(exceptions): better exception naming, add interface to group all exceptions --- src/AutoMapper.php | 4 ++-- ...MappingFoundException.php => AutoMapperException.php} | 2 +- src/Exception/BadMapDefinitionException.php | 2 +- src/Exception/CompileException.php | 2 +- src/Exception/InvalidArgumentException.php | 2 +- src/Exception/InvalidMappingException.php | 2 +- src/Exception/LogicException.php | 2 +- src/Exception/MetadataException.php | 9 +++++++++ src/Exception/MissingConstructorArgumentsException.php | 2 +- src/Exception/RuntimeException.php | 5 +---- src/Extractor/ReadAccessor.php | 4 ++-- src/Generator/CreateTargetStatementsGenerator.php | 4 ++-- src/Generator/MapperGenerator.php | 6 +++--- src/Generator/PropertyConditionsGenerator.php | 6 +++--- src/Loader/FileLoader.php | 4 ++-- src/MapperContext.php | 4 ++-- src/Transformer/ExpressionLanguageTransformer.php | 4 ++-- src/Transformer/FixedValueTransformer.php | 4 ++-- tests/AutoMapperTest.php | 6 +++--- tests/MapperContextTest.php | 3 ++- 20 files changed, 42 insertions(+), 35 deletions(-) rename src/Exception/{NoMappingFoundException.php => AutoMapperException.php} (66%) create mode 100644 src/Exception/MetadataException.php diff --git a/src/AutoMapper.php b/src/AutoMapper.php index 9dce8a4d..f8c601c2 100644 --- a/src/AutoMapper.php +++ b/src/AutoMapper.php @@ -4,7 +4,7 @@ namespace AutoMapper; -use AutoMapper\Exception\NoMappingFoundException; +use AutoMapper\Exception\InvalidMappingException; use AutoMapper\Generator\MapperGenerator; use AutoMapper\Generator\Shared\ClassDiscriminatorResolver; use AutoMapper\Loader\ClassLoaderInterface; @@ -109,7 +109,7 @@ public function map(array|object $source, string|array|object $target, array $co } if ('array' === $sourceType && 'array' === $targetType) { - throw new NoMappingFoundException('Cannot map this value, both source and target are array.'); + throw new InvalidMappingException('Cannot map this value, both source and target are array.'); } return $this->getMapper($sourceType, $targetType)->map($source, $context); diff --git a/src/Exception/NoMappingFoundException.php b/src/Exception/AutoMapperException.php similarity index 66% rename from src/Exception/NoMappingFoundException.php rename to src/Exception/AutoMapperException.php index a581cc9c..575ed442 100644 --- a/src/Exception/NoMappingFoundException.php +++ b/src/Exception/AutoMapperException.php @@ -7,6 +7,6 @@ /** * @author Joel Wurtz */ -final class NoMappingFoundException extends RuntimeException +interface AutoMapperException { } diff --git a/src/Exception/BadMapDefinitionException.php b/src/Exception/BadMapDefinitionException.php index 8b65e6f1..c5f7fc15 100644 --- a/src/Exception/BadMapDefinitionException.php +++ b/src/Exception/BadMapDefinitionException.php @@ -7,6 +7,6 @@ /** * @author Joel Wurtz */ -final class BadMapDefinitionException extends RuntimeException +final class BadMapDefinitionException extends MetadataException { } diff --git a/src/Exception/CompileException.php b/src/Exception/CompileException.php index ebde8551..9009677a 100644 --- a/src/Exception/CompileException.php +++ b/src/Exception/CompileException.php @@ -7,6 +7,6 @@ /** * @author Joel Wurtz */ -final class CompileException extends RuntimeException +final class CompileException extends \LogicException implements AutoMapperException { } diff --git a/src/Exception/InvalidArgumentException.php b/src/Exception/InvalidArgumentException.php index 2adacb52..072c80ac 100644 --- a/src/Exception/InvalidArgumentException.php +++ b/src/Exception/InvalidArgumentException.php @@ -7,6 +7,6 @@ /** * @author Baptiste Leduc */ -final class InvalidArgumentException extends \InvalidArgumentException +final class InvalidArgumentException extends \InvalidArgumentException implements AutoMapperException { } diff --git a/src/Exception/InvalidMappingException.php b/src/Exception/InvalidMappingException.php index 071260ba..67e15c5a 100644 --- a/src/Exception/InvalidMappingException.php +++ b/src/Exception/InvalidMappingException.php @@ -7,6 +7,6 @@ /** * @author Joel Wurtz */ -final class InvalidMappingException extends RuntimeException +final class InvalidMappingException extends MetadataException { } diff --git a/src/Exception/LogicException.php b/src/Exception/LogicException.php index 183ec959..dcdc791f 100644 --- a/src/Exception/LogicException.php +++ b/src/Exception/LogicException.php @@ -7,6 +7,6 @@ /** * @author Baptiste Leduc */ -final class LogicException extends \LogicException +final class LogicException extends \LogicException implements AutoMapperException { } diff --git a/src/Exception/MetadataException.php b/src/Exception/MetadataException.php new file mode 100644 index 00000000..afa46b5b --- /dev/null +++ b/src/Exception/MetadataException.php @@ -0,0 +1,9 @@ + - */ -class RuntimeException extends \RuntimeException +class RuntimeException extends \RuntimeException implements AutoMapperException { } diff --git a/src/Extractor/ReadAccessor.php b/src/Extractor/ReadAccessor.php index 5041685d..8b2d40f5 100644 --- a/src/Extractor/ReadAccessor.php +++ b/src/Extractor/ReadAccessor.php @@ -62,7 +62,7 @@ public function getExpression(Expr\Variable $input): Expr /* * Create method call argument to read value from context and throw exception if not found * - * $context['map_to_accessor_parameter']['some_key'] ?? throw new \InvalidArgumentException('error message'); + * $context['map_to_accessor_parameter']['some_key'] ?? throw new InvalidArgumentException('error message'); */ $methodCallArguments[] = new Arg( new Expr\BinaryOp\Coalesce( @@ -75,7 +75,7 @@ public function getExpression(Expr\Variable $input): Expr ), new Expr\Throw_( new Expr\New_( - new Name\FullyQualified(\InvalidArgumentException::class), + new Name\FullyQualified(InvalidArgumentException::class), [ new Arg( new Scalar\String_( diff --git a/src/Generator/CreateTargetStatementsGenerator.php b/src/Generator/CreateTargetStatementsGenerator.php index a330c8ff..055f2c73 100644 --- a/src/Generator/CreateTargetStatementsGenerator.php +++ b/src/Generator/CreateTargetStatementsGenerator.php @@ -4,7 +4,7 @@ namespace AutoMapper\Generator; -use AutoMapper\Exception\LogicException; +use AutoMapper\Exception\CompileException; use AutoMapper\Exception\MissingConstructorArgumentsException; use AutoMapper\Generator\Shared\CachedReflectionStatementsGenerator; use AutoMapper\Generator\Shared\DiscriminatorStatementsGenerator; @@ -323,6 +323,6 @@ private function getValueAsExpr(mixed $value): Expr return $expr->expr; } - throw new LogicException('Cannot extract expr from ' . var_export($value, true)); + throw new CompileException('Cannot extract expr from ' . var_export($value, true)); } } diff --git a/src/Generator/MapperGenerator.php b/src/Generator/MapperGenerator.php index 7446a0b3..e1e74368 100644 --- a/src/Generator/MapperGenerator.php +++ b/src/Generator/MapperGenerator.php @@ -7,7 +7,7 @@ use AutoMapper\AutoMapperRegistryInterface; use AutoMapper\Configuration; use AutoMapper\Exception\CompileException; -use AutoMapper\Exception\NoMappingFoundException; +use AutoMapper\Exception\InvalidMappingException; use AutoMapper\GeneratedMapper; use AutoMapper\Generator\Shared\CachedReflectionStatementsGenerator; use AutoMapper\Generator\Shared\ClassDiscriminatorResolver; @@ -59,12 +59,12 @@ public function __construct( * Generate Class AST given metadata for a mapper. * * @throws CompileException - * @throws NoMappingFoundException + * @throws InvalidMappingException */ public function generate(GeneratorMetadata $metadata): Stmt\Class_ { if ($this->disableGeneratedMapper) { - throw new NoMappingFoundException('No mapper found for source ' . $metadata->mapperMetadata->source . ' and target ' . $metadata->mapperMetadata->target); + throw new InvalidMappingException('No mapper found for source ' . $metadata->mapperMetadata->source . ' and target ' . $metadata->mapperMetadata->target); } return (new Builder\Class_($metadata->mapperMetadata->className)) diff --git a/src/Generator/PropertyConditionsGenerator.php b/src/Generator/PropertyConditionsGenerator.php index d3be6ffa..ecbb67d0 100644 --- a/src/Generator/PropertyConditionsGenerator.php +++ b/src/Generator/PropertyConditionsGenerator.php @@ -4,7 +4,7 @@ namespace AutoMapper\Generator; -use AutoMapper\Exception\LogicException; +use AutoMapper\Exception\CompileException; use AutoMapper\MapperContext; use AutoMapper\Metadata\GeneratorMetadata; use AutoMapper\Metadata\PropertyMetadata; @@ -259,7 +259,7 @@ private function customCondition(GeneratorMetadata $metadata, PropertyMetadata $ } if ($argumentsCount > 2) { - throw new LogicException('Callable condition must have 1 or 2 arguments required, but it has ' . $argumentsCount); + throw new CompileException('Callable condition must have 1 or 2 arguments required, but it has ' . $argumentsCount); } } @@ -303,6 +303,6 @@ private function customCondition(GeneratorMetadata $metadata, PropertyMetadata $ return $expr->expr; } - throw new LogicException('Cannot use callback or create expression language condition from expression "' . $propertyMetadata->if . "'"); + throw new CompileException('Cannot use callback or create expression language condition from expression "' . $propertyMetadata->if . "'"); } } diff --git a/src/Loader/FileLoader.php b/src/Loader/FileLoader.php index a37b9566..1bacc21d 100644 --- a/src/Loader/FileLoader.php +++ b/src/Loader/FileLoader.php @@ -4,7 +4,7 @@ namespace AutoMapper\Loader; -use AutoMapper\Exception\RuntimeException; +use AutoMapper\Exception\CompileException; use AutoMapper\Generator\MapperGenerator; use AutoMapper\Metadata\MapperMetadata; use AutoMapper\Metadata\MetadataFactory; @@ -129,7 +129,7 @@ private function write(string $file, string $contents): void $fp = fopen($file, 'w'); if (false === $fp) { - throw new RuntimeException(sprintf('Could not open file "%s"', $file)); + throw new CompileException(sprintf('Could not open file "%s"', $file)); } if (flock($fp, LOCK_EX)) { diff --git a/src/MapperContext.php b/src/MapperContext.php index 4c045921..14b46074 100644 --- a/src/MapperContext.php +++ b/src/MapperContext.php @@ -5,7 +5,7 @@ namespace AutoMapper; use AutoMapper\Exception\CircularReferenceException; -use AutoMapper\Exception\RuntimeException; +use AutoMapper\Exception\InvalidArgumentException; /** * Context for mapping. @@ -327,7 +327,7 @@ public static function getForcedTimezone(array $context): ?\DateTimeZone try { return new \DateTimeZone($timezone); } catch (\Exception $e) { - throw new RuntimeException("Invalid timezone \"$timezone\" passed to automapper context.", previous: $e); + throw new InvalidArgumentException("Invalid timezone \"$timezone\" passed to automapper context.", previous: $e); } } } diff --git a/src/Transformer/ExpressionLanguageTransformer.php b/src/Transformer/ExpressionLanguageTransformer.php index e826f186..2ddc74e4 100644 --- a/src/Transformer/ExpressionLanguageTransformer.php +++ b/src/Transformer/ExpressionLanguageTransformer.php @@ -4,7 +4,7 @@ namespace AutoMapper\Transformer; -use AutoMapper\Exception\LogicException; +use AutoMapper\Exception\CompileException; use AutoMapper\Generator\UniqueVariableScope; use AutoMapper\Metadata\PropertyMetadata; use PhpParser\Node\Expr; @@ -34,6 +34,6 @@ public function transform(Expr $input, Expr $target, PropertyMetadata $propertyM return [$expr->expr, []]; } - throw new LogicException('Cannot use callback or create expression language condition from expression "' . $this->expression . "'"); + throw new CompileException('Cannot use callback or create expression language condition from expression "' . $this->expression . "'"); } } diff --git a/src/Transformer/FixedValueTransformer.php b/src/Transformer/FixedValueTransformer.php index 9ec5bc9c..ad2f4d8d 100644 --- a/src/Transformer/FixedValueTransformer.php +++ b/src/Transformer/FixedValueTransformer.php @@ -4,7 +4,7 @@ namespace AutoMapper\Transformer; -use AutoMapper\Exception\LogicException; +use AutoMapper\Exception\CompileException; use AutoMapper\Generator\UniqueVariableScope; use AutoMapper\Metadata\PropertyMetadata; use PhpParser\Node\Expr; @@ -34,6 +34,6 @@ public function transform(Expr $input, Expr $target, PropertyMetadata $propertyM return [$expr->expr, []]; } - throw new LogicException('Cannot create php code from value ' . json_encode($this->value)); + throw new CompileException('Cannot create php code from value ' . json_encode($this->value)); } } diff --git a/tests/AutoMapperTest.php b/tests/AutoMapperTest.php index e6f8bdd9..553f5cc4 100644 --- a/tests/AutoMapperTest.php +++ b/tests/AutoMapperTest.php @@ -9,8 +9,8 @@ use AutoMapper\ConstructorStrategy; use AutoMapper\Event\PropertyMetadataEvent; use AutoMapper\Exception\CircularReferenceException; +use AutoMapper\Exception\InvalidMappingException; use AutoMapper\Exception\MissingConstructorArgumentsException; -use AutoMapper\Exception\NoMappingFoundException; use AutoMapper\Exception\ReadOnlyTargetException; use AutoMapper\MapperContext; use AutoMapper\Provider\EarlyReturn; @@ -769,7 +769,7 @@ public function testDiscriminator(): void public function testInvalidMappingBothArray(): void { - self::expectException(NoMappingFoundException::class); + $this->expectException(InvalidMappingException::class); $data = ['test' => 'foo']; $array = $this->autoMapper->map($data, 'array'); @@ -777,7 +777,7 @@ public function testInvalidMappingBothArray(): void public function testNoAutoRegister(): void { - self::expectException(NoMappingFoundException::class); + $this->expectException(InvalidMappingException::class); $automapper = AutoMapper::create(new Configuration(autoRegister: false, classPrefix: 'NoAutoRegister_')); $automapper->getMapper(Fixtures\User::class, Fixtures\UserDTO::class); diff --git a/tests/MapperContextTest.php b/tests/MapperContextTest.php index 746939cb..371a4d40 100644 --- a/tests/MapperContextTest.php +++ b/tests/MapperContextTest.php @@ -5,6 +5,7 @@ namespace AutoMapper\Tests; use AutoMapper\Exception\CircularReferenceException; +use AutoMapper\Exception\InvalidArgumentException; use AutoMapper\MapperContext; use PHPUnit\Framework\TestCase; @@ -159,7 +160,7 @@ public static function forcedTimeZoneProvider(): iterable public function testItThrowsExceptionWithInvalidTimeZone(): void { - $this->expectException(\RuntimeException::class); + $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Invalid timezone "foo" passed to automapper context.'); MapperContext::getForcedTimezone([MapperContext::DATETIME_FORCE_TIMEZONE => 'foo']);