diff --git a/src/Serializer/AbstractItemNormalizer.php b/src/Serializer/AbstractItemNormalizer.php index 7c12bf211d6..1b68581550c 100644 --- a/src/Serializer/AbstractItemNormalizer.php +++ b/src/Serializer/AbstractItemNormalizer.php @@ -224,9 +224,17 @@ public function denormalize(mixed $data, string $class, ?string $format = null, try { return $this->iriConverter->getResourceFromIri($data, $context + ['fetch_data' => true]); } catch (ItemNotFoundException $e) { - throw new UnexpectedValueException($e->getMessage(), $e->getCode(), $e); + if (!isset($context['not_normalizable_value_exceptions'])) { + throw new UnexpectedValueException($e->getMessage(), $e->getCode(), $e); + } + + throw NotNormalizableValueException::createForUnexpectedDataType(\sprintf('The type of the "%s" resource "string" (IRI), "%s" given.', $resourceClass, \gettype($data)), $data, [$resourceClass], $context['deserialization_path'] ?? null, true, $e->getCode(), $e); } catch (InvalidArgumentException $e) { - throw new UnexpectedValueException(\sprintf('Invalid IRI "%s".', $data), $e->getCode(), $e); + if (!isset($context['not_normalizable_value_exceptions'])) { + throw new UnexpectedValueException(\sprintf('Invalid IRI "%s".', $data), $e->getCode(), $e); + } + + throw NotNormalizableValueException::createForUnexpectedDataType(\sprintf('The type of the "%s" resource "string" (IRI), "%s" given.', $resourceClass, \gettype($data)), $data, [$resourceClass], $context['deserialization_path'] ?? null, true, $e->getCode(), $e); } } @@ -577,32 +585,14 @@ protected function denormalizeRelation(string $attributeName, ApiProperty $prope if (!isset($context['not_normalizable_value_exceptions'])) { throw new UnexpectedValueException($e->getMessage(), $e->getCode(), $e); } - $context['not_normalizable_value_exceptions'][] = NotNormalizableValueException::createForUnexpectedDataType( - $e->getMessage(), - $value, - [$className], - $context['deserialization_path'] ?? null, - true, - $e->getCode(), - $e - ); - - return null; + + throw NotNormalizableValueException::createForUnexpectedDataType($e->getMessage(), $value, [$className], $context['deserialization_path'] ?? null, true, $e->getCode(), $e); } catch (InvalidArgumentException $e) { if (!isset($context['not_normalizable_value_exceptions'])) { throw new UnexpectedValueException(\sprintf('Invalid IRI "%s".', $value), $e->getCode(), $e); } - $context['not_normalizable_value_exceptions'][] = NotNormalizableValueException::createForUnexpectedDataType( - $e->getMessage(), - $value, - [$className], - $context['deserialization_path'] ?? null, - true, - $e->getCode(), - $e - ); - - return null; + + throw NotNormalizableValueException::createForUnexpectedDataType($e->getMessage(), $value, [$className], $context['deserialization_path'] ?? null, true, $e->getCode(), $e); } } diff --git a/src/Serializer/Tests/AbstractItemNormalizerTest.php b/src/Serializer/Tests/AbstractItemNormalizerTest.php index b469d436923..8f627518129 100644 --- a/src/Serializer/Tests/AbstractItemNormalizerTest.php +++ b/src/Serializer/Tests/AbstractItemNormalizerTest.php @@ -50,7 +50,6 @@ use Symfony\Component\Serializer\Exception\UnexpectedValueException; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; -use Symfony\Component\Serializer\Serializer; use Symfony\Component\Serializer\SerializerInterface; /** @@ -913,6 +912,43 @@ public function testDeserializationPathForNotDenormalizableRelations(): void $this->assertSame('relatedDummies[0]', $errors[0]->getPath()); } + public function testDeserializationPathForNotDenormalizableResource(): void + { + $this->expectException(NotNormalizableValueException::class); + + $propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class); + + $propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class); + + $iriConverterProphecy = $this->prophesize(IriConverterInterface::class); + $iriConverterProphecy->getResourceFromIri(Argument::cetera())->willThrow(new InvalidArgumentException('Invalid IRI')); + + $resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class); + $resourceClassResolverProphecy->getResourceClass(null, Dummy::class)->willReturn(Dummy::class); + $resourceClassResolverProphecy->isResourceClass(Dummy::class)->willReturn(true); + + $propertyAccessorProphecy = $this->prophesize(PropertyAccessorInterface::class); + + $serializerProphecy = $this->prophesize(SerializerInterface::class); + $serializerProphecy->willImplement(DenormalizerInterface::class); + + $normalizer = $this->getMockForAbstractClass(AbstractItemNormalizer::class, [ + $propertyNameCollectionFactoryProphecy->reveal(), + $propertyMetadataFactoryProphecy->reveal(), + $iriConverterProphecy->reveal(), + $resourceClassResolverProphecy->reveal(), + $propertyAccessorProphecy->reveal(), + null, + null, + [], + null, + null, + ]); + $normalizer->setSerializer($serializerProphecy->reveal()); + + $normalizer->denormalize('wrong IRI', Dummy::class, null, ['not_normalizable_value_exceptions' => []]); + } + public function testInnerDocumentNotAllowed(): void { $this->expectException(UnexpectedValueException::class);