Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 689dfd9

Browse filesBrowse files
committed
Add COLLECT_EXTRA_ATTRIBUTES_ERRORS and full deserialization path
1 parent 06749b7 commit 689dfd9
Copy full SHA for 689dfd9

9 files changed

+290
-15
lines changed

‎src/Symfony/Component/Serializer/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Component/Serializer/CHANGELOG.md
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
6.2
5+
---
6+
* Add `COLLECT_EXTRA_ATTRIBUTES_ERRORS` option to `Serializer` to collect errors from nested denormalizations
7+
* Deprecate `PartialDenormalizationException::getErrors()`, call `getNotNormalizableValueErrors()` instead
8+
49
6.1
510
---
611

‎src/Symfony/Component/Serializer/Context/SerializerContextBuilder.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Serializer/Context/SerializerContextBuilder.php
+6Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\Serializer\Context;
1313

14+
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
1415
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
1516
use Symfony\Component\Serializer\Serializer;
1617

@@ -36,4 +37,9 @@ public function withCollectDenormalizationErrors(?bool $collectDenormalizationEr
3637
{
3738
return $this->with(DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS, $collectDenormalizationErrors);
3839
}
40+
41+
public function withCollectExtraAttributesErrors(?bool $collectExtraAttributesErrors): static
42+
{
43+
return $this->with(DenormalizerInterface::COLLECT_EXTRA_ATTRIBUTES_ERRORS, $collectExtraAttributesErrors);
44+
}
3945
}

‎src/Symfony/Component/Serializer/Exception/PartialDenormalizationException.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Serializer/Exception/PartialDenormalizationException.php
+28-4Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,45 @@
1717
class PartialDenormalizationException extends UnexpectedValueException
1818
{
1919
private $data;
20-
private $errors;
20+
/**
21+
* @var NotNormalizableValueException[]
22+
*/
23+
private array $notNormalizableErrors;
24+
private ?ExtraAttributesException $extraAttributesError = null;
2125

22-
public function __construct($data, array $errors)
26+
public function __construct($data, array $notNormalizableErrors, array $extraAttributesErrors = [])
2327
{
2428
$this->data = $data;
25-
$this->errors = $errors;
29+
$this->notNormalizableErrors = $notNormalizableErrors;
30+
$extraAttributes = [];
31+
foreach ($extraAttributesErrors as $error) {
32+
\array_push($extraAttributes, ...$error->getExtraAttributes());
33+
}
34+
if (\count($extraAttributes) > 0) {
35+
$this->extraAttributesError = new ExtraAttributesException($extraAttributes);
36+
}
2637
}
2738

2839
public function getData()
2940
{
3041
return $this->data;
3142
}
3243

44+
/**
45+
* @deprecated Use getNotNormalizableValueErrors() instead.
46+
*/
3347
public function getErrors(): array
3448
{
35-
return $this->errors;
49+
return $this->getNotNormalizableValueErrors();
50+
}
51+
52+
public function getNotNormalizableValueErrors(): array
53+
{
54+
return $this->notNormalizableErrors;
55+
}
56+
57+
public function getExtraAttributesError(): ?ExtraAttributesException
58+
{
59+
return $this->extraAttributesError;
3660
}
3761
}

‎src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php
+5-1Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,11 @@ public function denormalize(mixed $data, string $type, string $format = null, ar
423423
}
424424

425425
if (!empty($extraAttributes)) {
426-
throw new ExtraAttributesException($extraAttributes);
426+
$extraAttributeException = new ExtraAttributesException(array_map(fn (string $extraAttribute) => PropertyPath::append($context['deserialization_path'] ?? '', $extraAttribute), $extraAttributes));
427+
if (!isset($context['extra_attributes_exceptions'])) {
428+
throw $extraAttributeException;
429+
}
430+
$context['extra_attributes_exceptions'][] = $extraAttributeException;
427431
}
428432

429433
return $object;

‎src/Symfony/Component/Serializer/Normalizer/DenormalizerInterface.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Serializer/Normalizer/DenormalizerInterface.php
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,16 @@
2424
*/
2525
interface DenormalizerInterface
2626
{
27+
/**
28+
* Whether to collect all denormalization errors or to stop at first error.
29+
*/
2730
public const COLLECT_DENORMALIZATION_ERRORS = 'collect_denormalization_errors';
2831

32+
/**
33+
* Whether to collect all extra attributes errors or to stop at first nested error.
34+
*/
35+
public const COLLECT_EXTRA_ATTRIBUTES_ERRORS = 'collect_extra_attributes_errors';
36+
2937
/**
3038
* Denormalizes data back into an object of the given class.
3139
*

‎src/Symfony/Component/Serializer/Serializer.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Serializer/Serializer.php
+21-7Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@
1717
use Symfony\Component\Serializer\Encoder\ContextAwareEncoderInterface;
1818
use Symfony\Component\Serializer\Encoder\DecoderInterface;
1919
use Symfony\Component\Serializer\Encoder\EncoderInterface;
20+
use Symfony\Component\Serializer\Exception\ExtraAttributesException;
2021
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
2122
use Symfony\Component\Serializer\Exception\LogicException;
2223
use Symfony\Component\Serializer\Exception\NotEncodableValueException;
2324
use Symfony\Component\Serializer\Exception\NotNormalizableValueException;
2425
use Symfony\Component\Serializer\Exception\PartialDenormalizationException;
26+
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
2527
use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer;
2628
use Symfony\Component\Serializer\Normalizer\CacheableSupportsMethodInterface;
2729
use Symfony\Component\Serializer\Normalizer\ContextAwareDenormalizerInterface;
@@ -223,19 +225,31 @@ public function denormalize(mixed $data, string $type, string $format = null, ar
223225
throw new NotNormalizableValueException(sprintf('Could not denormalize object of type "%s", no supporting normalizer found.', $type));
224226
}
225227

228+
$notNormalizableExceptions = [];
226229
if (isset($context[DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS])) {
230+
if ($context[DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS]) {
231+
$context['not_normalizable_value_exceptions'] = [];
232+
$notNormalizableExceptions = &$context['not_normalizable_value_exceptions'];
233+
}
227234
unset($context[DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS]);
228-
$context['not_normalizable_value_exceptions'] = [];
229-
$errors = &$context['not_normalizable_value_exceptions'];
230-
$denormalized = $normalizer->denormalize($data, $type, $format, $context);
231-
if ($errors) {
232-
throw new PartialDenormalizationException($denormalized, $errors);
235+
}
236+
237+
$extraAttributesExceptions = [];
238+
if (isset($context[DenormalizerInterface::COLLECT_EXTRA_ATTRIBUTES_ERRORS])) {
239+
if ($context[DenormalizerInterface::COLLECT_EXTRA_ATTRIBUTES_ERRORS]) {
240+
$context['extra_attributes_exceptions'] = [];
241+
$extraAttributesExceptions = &$context['extra_attributes_exceptions'];
233242
}
243+
unset($context[DenormalizerInterface::COLLECT_EXTRA_ATTRIBUTES_ERRORS]);
244+
}
245+
246+
$denormalized = $normalizer->denormalize($data, $type, $format, $context);
234247

235-
return $denormalized;
248+
if (\count($notNormalizableExceptions) > 0 || \count($extraAttributesExceptions) > 0) {
249+
throw new PartialDenormalizationException($denormalized, $notNormalizableExceptions ?? [], $extraAttributesExceptions ?? []);
236250
}
237251

238-
return $normalizer->denormalize($data, $type, $format, $context);
252+
return $denormalized;
239253
}
240254

241255
/**

‎src/Symfony/Component/Serializer/Tests/Context/SerializerContextBuilderTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Serializer/Tests/Context/SerializerContextBuilderTest.php
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Component\Serializer\Context\SerializerContextBuilder;
16+
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
1617
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
1718
use Symfony\Component\Serializer\Serializer;
1819

@@ -38,6 +39,7 @@ public function testWithers(array $values)
3839
$context = $this->contextBuilder
3940
->withEmptyArrayAsObject($values[Serializer::EMPTY_ARRAY_AS_OBJECT])
4041
->withCollectDenormalizationErrors($values[DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS])
42+
->withCollectExtraAttributesErrors($values[DenormalizerInterface::COLLECT_EXTRA_ATTRIBUTES_ERRORS])
4143
->toArray();
4244

4345
$this->assertSame($values, $context);
@@ -51,11 +53,13 @@ public function withersDataProvider(): iterable
5153
yield 'With values' => [[
5254
Serializer::EMPTY_ARRAY_AS_OBJECT => true,
5355
DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS => false,
56+
DenormalizerInterface::COLLECT_EXTRA_ATTRIBUTES_ERRORS => false,
5457
]];
5558

5659
yield 'With null values' => [[
5760
Serializer::EMPTY_ARRAY_AS_OBJECT => null,
5861
DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS => null,
62+
DenormalizerInterface::COLLECT_EXTRA_ATTRIBUTES_ERRORS => null,
5963
]];
6064
}
6165
}

‎src/Symfony/Component/Serializer/Tests/Fixtures/Php74Full.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Serializer/Tests/Fixtures/Php74Full.php
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ final class Php74Full
3131
public DummyMessageInterface $dummyMessage;
3232
/** @var TestFoo[] $nestedArray */
3333
public TestFoo $nestedObject;
34+
public TestFoo $nestedObject2;
3435
}
3536

3637

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.