-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Serializer] Throw InvalidArgumentException if the data needed in the constructor doesn't belong to a backedEnum #47128
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Hey! I see that this is your first PR. That is great! Welcome! Symfony has a contribution guide which I suggest you to read. In short:
Review the GitHub status checks of your pull request and try to solve the reported issues. If some tests are failing, try to see if they are failing because of this change. When two Symfony core team members approve this change, it will be merged and you will become an official Symfony contributor! I am going to sit back now and wait for the reviews. Cheers! Carsonbot |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR! I'm not totally sure about the current patch though
src/Symfony/Component/Serializer/Normalizer/BackedEnumNormalizer.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/Serializer/Normalizer/BackedEnumNormalizer.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/Serializer/Tests/Fixtures/DummyObjectWithEnumConstructor.php
Outdated
Show resolved
Hide resolved
/cc @alexandre-daubois as you are the author of that normalizer |
62f439b
to
3451834
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me as it seems to fix the buggy case at hand as proven by the added tests.
… constructor doesn't belong to a backedEnum
Thank you @alli83. |
This pull-request doesn't seem to fix the targeted issue. While I understood the following argument of @alli83,
<?php
class SerializerIssueReport extends \PHPUnit\Framework\TestCase
{
public function testCollectErrorsOnEnum()
{
$serializer = new Symfony\Component\Serializer\Serializer(
[
new \Symfony\Component\Serializer\Normalizer\BackedEnumNormalizer(),
new \Symfony\Component\Serializer\Normalizer\ObjectNormalizer(),
],
['json' => new \Symfony\Component\Serializer\Encoder\JsonEncoder()]
);
$this->expectException(\Symfony\Component\Serializer\Exception\PartialDenormalizationException::class);
$serializer->deserialize('{"test": "invalid"}', DummyObject2::class, 'json', [
\Symfony\Component\Serializer\Normalizer\DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS => true
]);
}
}
// Original one, for this class the pull-req is legit.
class DummyObject {
public function __construct(public TestEnum $test) {}
}
// For this, PartialDenormalizationException can be thrown.
class DummyObject2 {
public TestEnum $test;
}
enum TestEnum: String
{
case Test = "test";
}
|
Indeed, we could distinguish the type of exception thrown depending on whether there is a constructor or not.
maybe when calling the instantiateObject from the AbstractNormalizer class we could easily add to the context to identify the presence of a constructor and direct the type of exception to throw ? thanks for your feedback 🙏 |
@alli83 Thank you for clarification. Could you kindly open a pull-req for it? |
Hi @alli83 Are you going to make a new PR to correct this? As it is now, we cannot have enums in our Dto's because we get InvalidArgumentException instead of PartialDenormalizationException that is expected when we specify collect_denormalization_errors |
indeed. I'm glad to have a look at it then for 5.4 ! |
Thanks |
To provide some context where I come from, I first viewed #43047 (comment) (Just to give you the background.) |
Would the added test case correspond to your case in #50192 ? |
…on outside construct method (alli83) This PR was merged into the 5.4 branch. Discussion ---------- [Serializer] backed enum throw notNormalizableValueException outside construct method | Q | A | ------------- | --- | Branch? | 5.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | #47128 (comment) | License | MIT | Doc PR | PR #47128 (comment) was aiming to throw an InvalidArgumentException if a constructor's argument is not a valid backedEnum( knowing an error will be thrown in all case e.g when it will be instantiated). This PR aims to throw a NotNormalizableValueException (like it was the case before) if an error occurs on an BackedEnum outside the case of the first PR So we have two different types of exceptions depending on whether it's an error at the constructor level or not. Commits ------- 5549493 [Serializer] Throw NotNormalizableValueException if it doesn't concern a backedEnum in construct method
Targeted case: Deserialization with "collect_denormalization_errors" set but the data to be serialized does not correspond to the scalar value of the targeted enum instance in the object's constructor.
updated in last commit : Keep "from "(in the previous commits I had switched to "tryFrom") to map the data submitted to an enum instance targeted.
Imho, even if the "collect_denormalization_errors" is specified, this type of error seems to have to be caught upstream. By just trying to collect the error we do not prevent the object from being instantiated. But this action is bound to fail because we already know that the data is not valid (checked by the BackedEnumNormalizer). This instantiation 'failure' leads to a confusing/misleading error (i.e. Argument # 1 ($test) must be of type TestEnum, string given) which is not the original error.