-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
Closed
Closed
Copy link
Description
Symfony version(s) affected
6.4
Description
PartialDenormalizationException
should be thrown in case collect_denormalization_errors
equal to true
.
But this is not true for the case when we're trying to denormalize array of values (for example UUIDs but it works for any case)
It happens as DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS is removed on the first iteration, see
symfony/src/Symfony/Component/Serializer/Serializer.php
Lines 214 to 236 in f91514d
if (isset($context[DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS])) { | |
unset($context[DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS]); | |
$context['not_normalizable_value_exceptions'] = []; | |
$errors = &$context['not_normalizable_value_exceptions']; | |
$denormalized = $normalizer->denormalize($data, $type, $format, $context); | |
if ($errors) { | |
// merge errors so that one path has only one error | |
$uniqueErrors = []; | |
foreach ($errors as $error) { | |
if (null === $error->getPath()) { | |
$uniqueErrors[] = $error; | |
continue; | |
} | |
$uniqueErrors[$error->getPath()] = $uniqueErrors[$error->getPath()] ?? $error; | |
} | |
throw new PartialDenormalizationException($denormalized, array_values($uniqueErrors)); | |
} | |
return $denormalized; | |
} |
I didn't check on earlier versions maybe it has never worked like I expect.
How to reproduce
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Exception\PartialDenormalizationException;
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Normalizer\UidNormalizer;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Uid\Uuid;
class Test
{
public array $uids;
public function __construct(Uuid ...$uids)
{
$this->uids = $uids;
}
}
$normalizers = [new UidNormalizer(), new ObjectNormalizer()];
$serializer = new Serializer($normalizers, [new JsonEncoder()]);
try {
$dto = $serializer->denormalize(
['uids' => [Uuid::v7()->toRfc4122(), '2024-01-15']],
Test::class,
'json',
[AbstractNormalizer::COLLECT_DENORMALIZATION_ERRORS => true]
);
} catch (PartialDenormalizationException $e) {
var_dump($e);
exit;
}
var_dump($dto);
Serializer will throw NotNormalizableValueException
instead of PartialDenormalizationException
and break collecting the normalization errors.
PHP Fatal error: Uncaught Symfony\Component\Serializer\Exception\NotNormalizableValueException: The data is not a valid "Symfony\Component\Uid\Uuid" string representation. in /home/projects/symfony-serializer/vendor/symfony/serializer/Exception/NotNormalizableValueException.php:32
Stack trace:
#0 /home/projects/symfony-serializer/vendor/symfony/serializer/Normalizer/UidNormalizer.php(81): Symfony\Component\Serializer\Exception\NotNormalizableValueException::createForUnexpectedDataType()
#1 /home/projects/symfony-serializer/vendor/symfony/serializer/Serializer.php(247): Symfony\Component\Serializer\Normalizer\UidNormalizer->denormalize()
#2 /home/projects/symfony-serializer/vendor/symfony/serializer/Normalizer/AbstractNormalizer.php(480): Symfony\Component\Serializer\Serializer->denormalize()
#3 /home/projects/symfony-serializer/vendor/symfony/serializer/Normalizer/AbstractObjectNormalizer.php(647): Symfony\Component\Serializer\Normalizer\AbstractNormalizer->denormalizeParameter()
#4 /home/projects/symfony-serializer/vendor/symfony/serializer/Normalizer/AbstractNormalizer.php(361): Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer->denormalizeParameter()
#5 /home/projects/symfony-serializer/vendor/symfony/serializer/Normalizer/AbstractObjectNormalizer.php(243): Symfony\Component\Serializer\Normalizer\AbstractNormalizer->instantiateObject()
#6 /home/projects/symfony-serializer/vendor/symfony/serializer/Normalizer/AbstractObjectNormalizer.php(349): Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer->instantiateObject()
#7 /home/projects/symfony-serializer/vendor/symfony/serializer/Serializer.php(227): Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer->denormalize()
#8 /home/projects/symfony-serializer/index.php(34): Symfony\Component\Serializer\Serializer->denormalize()
#9 {main}
thrown in /home/projects/symfony-serializer/vendor/symfony/serializer/Exception/NotNormalizableValueException.php on line 32
Possible Solution
No response
Additional Context
No response