Skip to content

Commit 0cd9b9f

Browse files
authored
fix: backport handling of union/intersection type in item normalizer (#7106)
1 parent 3faf5d4 commit 0cd9b9f

File tree

1 file changed

+53
-4
lines changed

1 file changed

+53
-4
lines changed

src/Serializer/AbstractItemNormalizer.php

+53-4
Original file line numberDiff line numberDiff line change
@@ -883,6 +883,7 @@ private function createAndValidateAttributeValue(string $attribute, mixed $value
883883
$propertyMetadata = $this->propertyMetadataFactory->create($context['resource_class'], $attribute, $this->getFactoryOptions($context));
884884
$types = $propertyMetadata->getBuiltinTypes() ?? [];
885885
$isMultipleTypes = \count($types) > 1;
886+
$denormalizationException = null;
886887

887888
foreach ($types as $type) {
888889
if (null === $value && ($type->isNullable() || ($context[static::DISABLE_TYPE_ENFORCEMENT] ?? false))) {
@@ -908,7 +909,18 @@ private function createAndValidateAttributeValue(string $attribute, mixed $value
908909
$context['resource_class'] = $resourceClass;
909910
unset($context['uri_variables']);
910911

911-
return $this->denormalizeCollection($attribute, $propertyMetadata, $type, $resourceClass, $value, $format, $context);
912+
try {
913+
return $this->denormalizeCollection($attribute, $propertyMetadata, $type, $resourceClass, $value, $format, $context);
914+
} catch (NotNormalizableValueException $e) {
915+
// union/intersect types: try the next type, if not valid, an exception will be thrown at the end
916+
if ($isMultipleTypes) {
917+
$denormalizationException ??= $e;
918+
919+
continue;
920+
}
921+
922+
throw $e;
923+
}
912924
}
913925

914926
if (
@@ -918,7 +930,18 @@ private function createAndValidateAttributeValue(string $attribute, mixed $value
918930
$resourceClass = $this->resourceClassResolver->getResourceClass(null, $className);
919931
$childContext = $this->createChildContext($this->createOperationContext($context, $resourceClass), $attribute, $format);
920932

921-
return $this->denormalizeRelation($attribute, $propertyMetadata, $resourceClass, $value, $format, $childContext);
933+
try {
934+
return $this->denormalizeRelation($attribute, $propertyMetadata, $resourceClass, $value, $format, $childContext);
935+
} catch (NotNormalizableValueException $e) {
936+
// union/intersect types: try the next type, if not valid, an exception will be thrown at the end
937+
if ($isMultipleTypes) {
938+
$denormalizationException ??= $e;
939+
940+
continue;
941+
}
942+
943+
throw $e;
944+
}
922945
}
923946

924947
if (
@@ -933,7 +956,18 @@ private function createAndValidateAttributeValue(string $attribute, mixed $value
933956

934957
unset($context['resource_class'], $context['uri_variables']);
935958

936-
return $this->serializer->denormalize($value, $className.'[]', $format, $context);
959+
try {
960+
return $this->serializer->denormalize($value, $className.'[]', $format, $context);
961+
} catch (NotNormalizableValueException $e) {
962+
// union/intersect types: try the next type, if not valid, an exception will be thrown at the end
963+
if ($isMultipleTypes) {
964+
$denormalizationException ??= $e;
965+
966+
continue;
967+
}
968+
969+
throw $e;
970+
}
937971
}
938972

939973
if (null !== $className = $type->getClassName()) {
@@ -943,7 +977,18 @@ private function createAndValidateAttributeValue(string $attribute, mixed $value
943977

944978
unset($context['resource_class'], $context['uri_variables']);
945979

946-
return $this->serializer->denormalize($value, $className, $format, $context);
980+
try {
981+
return $this->serializer->denormalize($value, $className, $format, $context);
982+
} catch (NotNormalizableValueException $e) {
983+
// union/intersect types: try the next type, if not valid, an exception will be thrown at the end
984+
if ($isMultipleTypes) {
985+
$denormalizationException ??= $e;
986+
987+
continue;
988+
}
989+
990+
throw $e;
991+
}
947992
}
948993

949994
/* From @see AbstractObjectNormalizer::validateAndDenormalize() */
@@ -1019,6 +1064,10 @@ private function createAndValidateAttributeValue(string $attribute, mixed $value
10191064
}
10201065
}
10211066

1067+
if ($denormalizationException) {
1068+
throw $denormalizationException;
1069+
}
1070+
10221071
return $value;
10231072
}
10241073

0 commit comments

Comments
 (0)