diff --git a/src/TypeCaster/HydratorTypeCaster.php b/src/TypeCaster/HydratorTypeCaster.php index 6e03a15..5dea7a9 100644 --- a/src/TypeCaster/HydratorTypeCaster.php +++ b/src/TypeCaster/HydratorTypeCaster.php @@ -7,6 +7,7 @@ use ReflectionClass; use ReflectionNamedType; use ReflectionUnionType; +use Yiisoft\Hydrator\Exception\NonInstantiableException; use Yiisoft\Hydrator\HydratorInterface; use Yiisoft\Hydrator\Result; @@ -58,9 +59,12 @@ private function castInternal(array $value, ReflectionNamedType $type, HydratorI $reflection = new ReflectionClass($class); if ($reflection->isInstantiable()) { - return Result::success( - $hydrator->create($class, $value) - ); + try { + $object = $hydrator->create($class, $value); + } catch (NonInstantiableException) { + return Result::fail(); + } + return Result::success($object); } return Result::fail(); diff --git a/tests/Support/PrivateConstructorObject.php b/tests/Support/PrivateConstructorObject.php new file mode 100644 index 0000000..211e020 --- /dev/null +++ b/tests/Support/PrivateConstructorObject.php @@ -0,0 +1,12 @@ + 'hello'], $this->createContext(static fn(StringableObject|(Stringable&Countable) $object) => null), ], + 'incompatible array to union type with intersection type' => [ + Result::fail(), + ['var' => 'hello'], + $this->createContext(static fn(StringableObject|(Stringable&Countable) $object) => null), + ], ]; } diff --git a/tests/TypeCaster/HydratorTypeCasterTest.php b/tests/TypeCaster/HydratorTypeCasterTest.php index 7bd60b4..dd3b594 100644 --- a/tests/TypeCaster/HydratorTypeCasterTest.php +++ b/tests/TypeCaster/HydratorTypeCasterTest.php @@ -9,6 +9,7 @@ use ReflectionFunction; use Yiisoft\Hydrator\Hydrator; use Yiisoft\Hydrator\Result; +use Yiisoft\Hydrator\Tests\Support\PrivateConstructorObject; use Yiisoft\Hydrator\Tests\Support\StringableObject; use Yiisoft\Hydrator\TypeCaster\HydratorTypeCaster; use Yiisoft\Hydrator\TypeCaster\TypeCastContext; @@ -48,6 +49,11 @@ public function dataBase(): array ['string' => 'hello'], $this->createContext(static fn(int|StringableObject $object) => null), ], + 'array to non-instantiable object' => [ + Result::fail(), + ['string' => 'hello'], + $this->createContext(static fn(PrivateConstructorObject $object) => null), + ], ]; }