From 43d028d5ba2bc6cd4dd28ea1ac6823437572a1b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?THERAGE=20K=C3=A9vin?= Date: Mon, 27 Mar 2023 14:28:52 +0200 Subject: [PATCH] [Serializer] Fix MissingConstructorArgumentsException returning missing argument one by one --- UPGRADE-6.3.md | 1 - src/Symfony/Component/Serializer/CHANGELOG.md | 1 - .../MissingConstructorArgumentException.php | 41 ------------------- .../MissingConstructorArgumentsException.php | 34 +++++++-------- .../Normalizer/AbstractNormalizer.php | 35 +++++++++------- .../Normalizer/AbstractObjectNormalizer.php | 14 +++---- .../ConstructorArgumentsTestTrait.php | 11 +++-- 7 files changed, 49 insertions(+), 88 deletions(-) delete mode 100644 src/Symfony/Component/Serializer/Exception/MissingConstructorArgumentException.php diff --git a/UPGRADE-6.3.md b/UPGRADE-6.3.md index a05514396074c..5600e12873e47 100644 --- a/UPGRADE-6.3.md +++ b/UPGRADE-6.3.md @@ -133,7 +133,6 @@ Validator Serializer ---------- - * Deprecate `MissingConstructorArgumentsException` in favor of `MissingConstructorArgumentException` * Deprecate `CacheableSupportsMethodInterface` in favor of the new `getSupportedTypes(?string $format)` methods * The following Normalizer classes will become final in 7.0: * `ConstraintViolationListNormalizer` diff --git a/src/Symfony/Component/Serializer/CHANGELOG.md b/src/Symfony/Component/Serializer/CHANGELOG.md index 7c2dd31143551..692226968f2c0 100644 --- a/src/Symfony/Component/Serializer/CHANGELOG.md +++ b/src/Symfony/Component/Serializer/CHANGELOG.md @@ -9,7 +9,6 @@ CHANGELOG * Add `UnsupportedFormatException` which is thrown when there is no decoder for a given format * Add method `getSupportedTypes(?string $format)` to `NormalizerInterface` and `DenormalizerInterface` * Make `ProblemNormalizer` give details about `ValidationFailedException` and `PartialDenormalizationException` - * Deprecate `MissingConstructorArgumentsException` in favor of `MissingConstructorArgumentException` * Deprecate `CacheableSupportsMethodInterface` in favor of the new `getSupportedTypes(?string $format)` methods * The following Normalizer classes will become final in 7.0: * `ConstraintViolationListNormalizer` diff --git a/src/Symfony/Component/Serializer/Exception/MissingConstructorArgumentException.php b/src/Symfony/Component/Serializer/Exception/MissingConstructorArgumentException.php deleted file mode 100644 index 3fdfaf605869e..0000000000000 --- a/src/Symfony/Component/Serializer/Exception/MissingConstructorArgumentException.php +++ /dev/null @@ -1,41 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Serializer\Exception; - -class MissingConstructorArgumentException extends MissingConstructorArgumentsException -{ - private string $class; - private string $missingArgument; - - /** - * @param class-string $class - */ - public function __construct(string $class, string $missingArgument, int $code = 0, \Throwable $previous = null) - { - $this->class = $class; - $this->missingArgument = $missingArgument; - - $message = sprintf('Cannot create an instance of "%s" from serialized data because its constructor requires parameter "%s" to be present.', $class, $missingArgument); - - parent::__construct($message, $code, $previous, [$missingArgument]); - } - - public function getClass(): string - { - return $this->class; - } - - public function getMissingArgument(): string - { - return $this->missingArgument; - } -} diff --git a/src/Symfony/Component/Serializer/Exception/MissingConstructorArgumentsException.php b/src/Symfony/Component/Serializer/Exception/MissingConstructorArgumentsException.php index a5a71d00cf62a..ee8fcb5dc22e5 100644 --- a/src/Symfony/Component/Serializer/Exception/MissingConstructorArgumentsException.php +++ b/src/Symfony/Component/Serializer/Exception/MissingConstructorArgumentsException.php @@ -12,37 +12,37 @@ namespace Symfony\Component\Serializer\Exception; /** - * @deprecated since Symfony 6.3, use {@see MissingConstructorArgumentException} instead - * * @author Maxime VEBER */ class MissingConstructorArgumentsException extends RuntimeException { /** - * @var string[] + * @param string[] $missingArguments + * @param class-string|null $class */ - private $missingArguments; - - public function __construct(string $message, int $code = 0, \Throwable $previous = null, array $missingArguments = []) - { - if (!$this instanceof MissingConstructorArgumentException) { - trigger_deprecation('symfony/serializer', '6.3', 'The "%s" class is deprecated, use "%s" instead.', __CLASS__, MissingConstructorArgumentException::class); - } - - $this->missingArguments = $missingArguments; - + public function __construct( + string $message, + int $code = 0, + \Throwable $previous = null, + private array $missingArguments = [], + private ?string $class = null, + ) { parent::__construct($message, $code, $previous); } /** - * @deprecated since Symfony 6.3, use {@see MissingConstructorArgumentException::getMissingArgument()} instead - * * @return string[] */ public function getMissingConstructorArguments(): array { - trigger_deprecation('symfony/serializer', '6.3', 'The "%s()" method is deprecated, use "%s::getMissingArgument()" instead.', __METHOD__, MissingConstructorArgumentException::class); - return $this->missingArguments; } + + /** + * @return class-string|null + */ + public function getClass(): ?string + { + return $this->class; + } } diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php index 856aefbe985bc..61b14a1a8008f 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php @@ -14,7 +14,7 @@ use Symfony\Component\Serializer\Exception\CircularReferenceException; use Symfony\Component\Serializer\Exception\InvalidArgumentException; use Symfony\Component\Serializer\Exception\LogicException; -use Symfony\Component\Serializer\Exception\MissingConstructorArgumentException; +use Symfony\Component\Serializer\Exception\MissingConstructorArgumentsException; use Symfony\Component\Serializer\Exception\NotNormalizableValueException; use Symfony\Component\Serializer\Exception\RuntimeException; use Symfony\Component\Serializer\Mapping\AttributeMetadataInterface; @@ -313,7 +313,7 @@ protected function getConstructor(array &$data, string $class, array &$context, * @return object * * @throws RuntimeException - * @throws MissingConstructorArgumentException + * @throws MissingConstructorArgumentsException */ protected function instantiateObject(array &$data, string $class, array &$context, \ReflectionClass $reflectionClass, array|bool $allowedAttributes, string $format = null) { @@ -332,7 +332,7 @@ protected function instantiateObject(array &$data, string $class, array &$contex } $constructorParameters = $constructor->getParameters(); - + $missingConstructorArguments = []; $params = []; foreach ($constructorParameters as $constructorParameter) { $paramName = $constructorParameter->name; @@ -386,7 +386,8 @@ protected function instantiateObject(array &$data, string $class, array &$contex $params[] = null; } else { if (!isset($context['not_normalizable_value_exceptions'])) { - throw new MissingConstructorArgumentException($class, $constructorParameter->name); + $missingConstructorArguments[] = $constructorParameter->name; + continue; } $exception = NotNormalizableValueException::createForUnexpectedDataType( @@ -402,19 +403,23 @@ protected function instantiateObject(array &$data, string $class, array &$contex } } - if ($constructor->isConstructor()) { - try { - return $reflectionClass->newInstanceArgs($params); - } catch (\TypeError $e) { - if (!isset($context['not_normalizable_value_exceptions'])) { - throw $e; - } + if ($missingConstructorArguments) { + throw new MissingConstructorArgumentsException(sprintf('Cannot create an instance of "%s" from serialized data because its constructor requires the following parameters to be present : "$%s".', $class, implode('", "$', $missingConstructorArguments)), 0, null, $missingConstructorArguments, $class); + } - return $reflectionClass->newInstanceWithoutConstructor(); - } - } else { + if (!$constructor->isConstructor()) { return $constructor->invokeArgs(null, $params); } + + try { + return $reflectionClass->newInstanceArgs($params); + } catch (\TypeError $e) { + if (!isset($context['not_normalizable_value_exceptions'])) { + throw $e; + } + + return $reflectionClass->newInstanceWithoutConstructor(); + } } return new $class(); @@ -438,7 +443,7 @@ protected function denormalizeParameter(\ReflectionClass $class, \ReflectionPara } } catch (\ReflectionException $e) { throw new RuntimeException(sprintf('Could not determine the class of the parameter "%s".', $parameterName), 0, $e); - } catch (MissingConstructorArgumentException $e) { + } catch (MissingConstructorArgumentsException $e) { if (!$parameter->getType()->allowsNull()) { throw $e; } diff --git a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php index 88e3c3ea120bd..16b2bb70af3fc 100644 --- a/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php +++ b/src/Symfony/Component/Serializer/Normalizer/AbstractObjectNormalizer.php @@ -22,7 +22,7 @@ use Symfony\Component\Serializer\Encoder\XmlEncoder; use Symfony\Component\Serializer\Exception\ExtraAttributesException; use Symfony\Component\Serializer\Exception\LogicException; -use Symfony\Component\Serializer\Exception\MissingConstructorArgumentException; +use Symfony\Component\Serializer\Exception\MissingConstructorArgumentsException; use Symfony\Component\Serializer\Exception\NotNormalizableValueException; use Symfony\Component\Serializer\Mapping\AttributeMetadataInterface; use Symfony\Component\Serializer\Mapping\ClassDiscriminatorFromClassMetadata; @@ -419,7 +419,7 @@ abstract protected function setAttributeValue(object $object, string $attribute, * * @throws NotNormalizableValueException * @throws ExtraAttributesException - * @throws MissingConstructorArgumentException + * @throws MissingConstructorArgumentsException * @throws LogicException */ private function validateAndDenormalize(array $types, string $currentClass, string $attribute, mixed $data, ?string $format, array $context): mixed @@ -427,7 +427,7 @@ private function validateAndDenormalize(array $types, string $currentClass, stri $expectedTypes = []; $isUnionType = \count($types) > 1; $extraAttributesException = null; - $missingConstructorArgumentException = null; + $missingConstructorArgumentsException = null; foreach ($types as $type) { if (null === $data && $type->isNullable()) { return null; @@ -567,12 +567,12 @@ private function validateAndDenormalize(array $types, string $currentClass, stri } $extraAttributesException ??= $e; - } catch (MissingConstructorArgumentException $e) { + } catch (MissingConstructorArgumentsException $e) { if (!$isUnionType) { throw $e; } - $missingConstructorArgumentException ??= $e; + $missingConstructorArgumentsException ??= $e; } } @@ -580,8 +580,8 @@ private function validateAndDenormalize(array $types, string $currentClass, stri throw $extraAttributesException; } - if ($missingConstructorArgumentException) { - throw $missingConstructorArgumentException; + if ($missingConstructorArgumentsException) { + throw $missingConstructorArgumentsException; } if ($context[self::DISABLE_TYPE_ENFORCEMENT] ?? $this->defaultContext[self::DISABLE_TYPE_ENFORCEMENT] ?? false) { diff --git a/src/Symfony/Component/Serializer/Tests/Normalizer/Features/ConstructorArgumentsTestTrait.php b/src/Symfony/Component/Serializer/Tests/Normalizer/Features/ConstructorArgumentsTestTrait.php index 9489136be2cb9..928ded512e935 100644 --- a/src/Symfony/Component/Serializer/Tests/Normalizer/Features/ConstructorArgumentsTestTrait.php +++ b/src/Symfony/Component/Serializer/Tests/Normalizer/Features/ConstructorArgumentsTestTrait.php @@ -11,7 +11,7 @@ namespace Symfony\Component\Serializer\Tests\Normalizer\Features; -use Symfony\Component\Serializer\Exception\MissingConstructorArgumentException; +use Symfony\Component\Serializer\Exception\MissingConstructorArgumentsException; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; use Symfony\Component\Serializer\Tests\Fixtures\NotSerializedConstructorArgumentDummy; @@ -62,14 +62,13 @@ public function testConstructorWithMissingData() ]; $normalizer = $this->getDenormalizerForConstructArguments(); - try { $normalizer->denormalize($data, ConstructorArgumentsObject::class); - self::fail(sprintf('Failed asserting that exception of type "%s" is thrown.', MissingConstructorArgumentException::class)); - } catch (MissingConstructorArgumentException $e) { - self::assertSame(sprintf('Cannot create an instance of "%s" from serialized data because its constructor requires parameter "bar" to be present.', ConstructorArgumentsObject::class), $e->getMessage()); + self::fail(sprintf('Failed asserting that exception of type "%s" is thrown.', MissingConstructorArgumentsException::class)); + } catch (MissingConstructorArgumentsException $e) { + self::assertSame(sprintf('Cannot create an instance of "%s" from serialized data because its constructor requires the following parameters to be present : "$bar", "$baz".', ConstructorArgumentsObject::class), $e->getMessage()); self::assertSame(ConstructorArgumentsObject::class, $e->getClass()); - self::assertSame('bar', $e->getMissingArgument()); + self::assertSame(['bar', 'baz'], $e->getMissingConstructorArguments()); } } } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy