Skip to content

Commit f55606b

Browse files
authored
fix(serializer): throw NotNormalizableValueException when resource not found or invalid IRI on denormalization
1 parent 95242f6 commit f55606b

File tree

2 files changed

+51
-25
lines changed

2 files changed

+51
-25
lines changed

src/Serializer/AbstractItemNormalizer.php

+14-24
Original file line numberDiff line numberDiff line change
@@ -224,9 +224,17 @@ public function denormalize(mixed $data, string $class, ?string $format = null,
224224
try {
225225
return $this->iriConverter->getResourceFromIri($data, $context + ['fetch_data' => true]);
226226
} catch (ItemNotFoundException $e) {
227-
throw new UnexpectedValueException($e->getMessage(), $e->getCode(), $e);
227+
if (!isset($context['not_normalizable_value_exceptions'])) {
228+
throw new UnexpectedValueException($e->getMessage(), $e->getCode(), $e);
229+
}
230+
231+
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);
228232
} catch (InvalidArgumentException $e) {
229-
throw new UnexpectedValueException(\sprintf('Invalid IRI "%s".', $data), $e->getCode(), $e);
233+
if (!isset($context['not_normalizable_value_exceptions'])) {
234+
throw new UnexpectedValueException(\sprintf('Invalid IRI "%s".', $data), $e->getCode(), $e);
235+
}
236+
237+
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);
230238
}
231239
}
232240

@@ -577,32 +585,14 @@ protected function denormalizeRelation(string $attributeName, ApiProperty $prope
577585
if (!isset($context['not_normalizable_value_exceptions'])) {
578586
throw new UnexpectedValueException($e->getMessage(), $e->getCode(), $e);
579587
}
580-
$context['not_normalizable_value_exceptions'][] = NotNormalizableValueException::createForUnexpectedDataType(
581-
$e->getMessage(),
582-
$value,
583-
[$className],
584-
$context['deserialization_path'] ?? null,
585-
true,
586-
$e->getCode(),
587-
$e
588-
);
589-
590-
return null;
588+
589+
throw NotNormalizableValueException::createForUnexpectedDataType($e->getMessage(), $value, [$className], $context['deserialization_path'] ?? null, true, $e->getCode(), $e);
591590
} catch (InvalidArgumentException $e) {
592591
if (!isset($context['not_normalizable_value_exceptions'])) {
593592
throw new UnexpectedValueException(\sprintf('Invalid IRI "%s".', $value), $e->getCode(), $e);
594593
}
595-
$context['not_normalizable_value_exceptions'][] = NotNormalizableValueException::createForUnexpectedDataType(
596-
$e->getMessage(),
597-
$value,
598-
[$className],
599-
$context['deserialization_path'] ?? null,
600-
true,
601-
$e->getCode(),
602-
$e
603-
);
604-
605-
return null;
594+
595+
throw NotNormalizableValueException::createForUnexpectedDataType($e->getMessage(), $value, [$className], $context['deserialization_path'] ?? null, true, $e->getCode(), $e);
606596
}
607597
}
608598

src/Serializer/Tests/AbstractItemNormalizerTest.php

+37-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
5151
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
5252
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
53-
use Symfony\Component\Serializer\Serializer;
5453
use Symfony\Component\Serializer\SerializerInterface;
5554

5655
/**
@@ -913,6 +912,43 @@ public function testDeserializationPathForNotDenormalizableRelations(): void
913912
$this->assertSame('relatedDummies[0]', $errors[0]->getPath());
914913
}
915914

915+
public function testDeserializationPathForNotDenormalizableResource(): void
916+
{
917+
$this->expectException(NotNormalizableValueException::class);
918+
919+
$propertyNameCollectionFactoryProphecy = $this->prophesize(PropertyNameCollectionFactoryInterface::class);
920+
921+
$propertyMetadataFactoryProphecy = $this->prophesize(PropertyMetadataFactoryInterface::class);
922+
923+
$iriConverterProphecy = $this->prophesize(IriConverterInterface::class);
924+
$iriConverterProphecy->getResourceFromIri(Argument::cetera())->willThrow(new InvalidArgumentException('Invalid IRI'));
925+
926+
$resourceClassResolverProphecy = $this->prophesize(ResourceClassResolverInterface::class);
927+
$resourceClassResolverProphecy->getResourceClass(null, Dummy::class)->willReturn(Dummy::class);
928+
$resourceClassResolverProphecy->isResourceClass(Dummy::class)->willReturn(true);
929+
930+
$propertyAccessorProphecy = $this->prophesize(PropertyAccessorInterface::class);
931+
932+
$serializerProphecy = $this->prophesize(SerializerInterface::class);
933+
$serializerProphecy->willImplement(DenormalizerInterface::class);
934+
935+
$normalizer = $this->getMockForAbstractClass(AbstractItemNormalizer::class, [
936+
$propertyNameCollectionFactoryProphecy->reveal(),
937+
$propertyMetadataFactoryProphecy->reveal(),
938+
$iriConverterProphecy->reveal(),
939+
$resourceClassResolverProphecy->reveal(),
940+
$propertyAccessorProphecy->reveal(),
941+
null,
942+
null,
943+
[],
944+
null,
945+
null,
946+
]);
947+
$normalizer->setSerializer($serializerProphecy->reveal());
948+
949+
$normalizer->denormalize('wrong IRI', Dummy::class, null, ['not_normalizable_value_exceptions' => []]);
950+
}
951+
916952
public function testInnerDocumentNotAllowed(): void
917953
{
918954
$this->expectException(UnexpectedValueException::class);

0 commit comments

Comments
 (0)