Skip to content

Commit 0df5af2

Browse files
Merge branch '6.4' into 7.3
* 6.4: [Serializer] Fix unknown type in denormalization errors when union type used in constructor [HttpKernel] Handle an array vary header in the http cache store for write [Console] Fix handling of `\E` in Bash completion
2 parents 0c3dd92 + 48d0477 commit 0df5af2

File tree

3 files changed

+89
-4
lines changed

3 files changed

+89
-4
lines changed

Normalizer/AbstractNormalizer.php

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -396,16 +396,22 @@ protected function instantiateObject(array &$data, string $class, array &$contex
396396
continue;
397397
}
398398

399-
$constructorParameterType = 'unknown';
399+
$constructorParameterTypes = [];
400400
$reflectionType = $constructorParameter->getType();
401-
if ($reflectionType instanceof \ReflectionNamedType) {
402-
$constructorParameterType = $reflectionType->getName();
401+
if ($reflectionType instanceof \ReflectionUnionType) {
402+
foreach ($reflectionType->getTypes() as $reflectionType) {
403+
$constructorParameterTypes[] = (string) $reflectionType;
404+
}
405+
} elseif ($reflectionType instanceof \ReflectionType) {
406+
$constructorParameterTypes[] = (string) $reflectionType;
407+
} else {
408+
$constructorParameterTypes[] = 'unknown';
403409
}
404410

405411
$exception = NotNormalizableValueException::createForUnexpectedDataType(
406412
\sprintf('Failed to create object because the class misses the "%s" property.', $constructorParameter->name),
407413
null,
408-
[$constructorParameterType],
414+
$constructorParameterTypes,
409415
$attributeContext['deserialization_path'] ?? null,
410416
true
411417
);

Tests/Fixtures/DummyWithUnion.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Serializer\Tests\Fixtures;
13+
14+
/**
15+
* @author Dmitrii <github.com/d-mitrofanov-v>
16+
*/
17+
class DummyWithUnion
18+
{
19+
public function __construct(
20+
public int|float $value,
21+
public string|int $value2,
22+
) {
23+
}
24+
}

Tests/SerializerTest.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
use Symfony\Component\Serializer\Tests\Fixtures\DummyObjectWithEnumConstructor;
6868
use Symfony\Component\Serializer\Tests\Fixtures\DummyObjectWithEnumProperty;
6969
use Symfony\Component\Serializer\Tests\Fixtures\DummyWithObjectOrNull;
70+
use Symfony\Component\Serializer\Tests\Fixtures\DummyWithUnion;
7071
use Symfony\Component\Serializer\Tests\Fixtures\DummyWithVariadicParameter;
7172
use Symfony\Component\Serializer\Tests\Fixtures\FalseBuiltInDummy;
7273
use Symfony\Component\Serializer\Tests\Fixtures\FooImplementationDummy;
@@ -1429,6 +1430,60 @@ public function testCollectDenormalizationErrorsWithInvalidConstructorTypes()
14291430
$this->assertSame($expected, $exceptionsAsArray);
14301431
}
14311432

1433+
public function testCollectDenormalizationErrorsWithUnionConstructorTypes()
1434+
{
1435+
$json = '{}';
1436+
1437+
$serializer = new Serializer(
1438+
[new ObjectNormalizer()],
1439+
['json' => new JsonEncoder()]
1440+
);
1441+
1442+
try {
1443+
$serializer->deserialize(
1444+
$json,
1445+
DummyWithUnion::class,
1446+
'json',
1447+
[DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS => true]
1448+
);
1449+
1450+
$this->fail();
1451+
} catch (\Throwable $th) {
1452+
$this->assertInstanceOf(PartialDenormalizationException::class, $th);
1453+
}
1454+
1455+
$exceptionsAsArray = array_map(fn (NotNormalizableValueException $e): array => [
1456+
'currentType' => $e->getCurrentType(),
1457+
'expectedTypes' => $e->getExpectedTypes(),
1458+
'path' => $e->getPath(),
1459+
'useMessageForUser' => $e->canUseMessageForUser(),
1460+
'message' => $e->getMessage(),
1461+
], $th->getErrors());
1462+
1463+
$expected = [
1464+
[
1465+
'currentType' => 'null',
1466+
'expectedTypes' => [
1467+
'int', 'float',
1468+
],
1469+
'path' => 'value',
1470+
'useMessageForUser' => true,
1471+
'message' => 'Failed to create object because the class misses the "value" property.',
1472+
],
1473+
[
1474+
'currentType' => 'null',
1475+
'expectedTypes' => [
1476+
'string', 'int',
1477+
],
1478+
'path' => 'value2',
1479+
'useMessageForUser' => true,
1480+
'message' => 'Failed to create object because the class misses the "value2" property.',
1481+
],
1482+
];
1483+
1484+
$this->assertSame($expected, $exceptionsAsArray);
1485+
}
1486+
14321487
public function testCollectDenormalizationErrorsWithEnumConstructor()
14331488
{
14341489
$serializer = new Serializer(

0 commit comments

Comments
 (0)