Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork9.6k
[Serializer] DocumentSerializerInterface
exceptions#59306
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
Any method everywhere might throw some type of |
VincentLanglet commentedDec 27, 2024 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
This is not true. Some methods (a lot) doesn't throws Exception at all, even in the Symfony codebase. And with well-documented methods, PHPStan helps a lot catching unwanted exceptions Currently, with code like
I'm getting
because the PHPdoc is not describing the exceptions thrown.
Notice I didn't added
It adds value for static analysis tools (like PHPStan) users.
And a
I don't see a reason to add it to SerializerInterface which is a similar interface. For reference, I already added missing |
I agree with@wouterj. If we think it's useful, we should do it consistently across the board, not just on one interface. Maybe it's mostly useful for interfaces? But then, do we want to reference the interface or the concrete exception implementations that can be thrown? |
VincentLanglet commentedDec 29, 2024 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
There is already a looot of method/class/interface already with
Since people works mainly with interface, it is. This also explains which exceptions we are supposed to throw when implementing the interface. It throws:
And
So far, I would say both of the strategy are used. For instance symfony/src/Symfony/Component/Serializer/Normalizer/DenormalizerInterface.php Lines 37 to 43 in78f4d9a
We can list all the exceptions thrown with the explanation of the reason but we still have to add a
I considered it was already a good step to add |
wouterj commentedDec 29, 2024 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
Thinking about this more, I'm actually thinking the They are documenting a contract ("this method will only throw things that are instance of X") while there is no way to enforce that. Even more, retrospectively adding it to methods creates a new contract for any implementation that they were never aware of. I would say this means that adding |
wouterj commentedDec 29, 2024 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
And this is not a theoretical thing. It took me only a quick look to find Symfony itself does not conform this new contract proposed in the PR: useSymfony\Component\Serializer\Encoder\YamlEncoder;useSymfony\Component\Serializer\Normalizer\ObjectNormalizer;useSymfony\Component\Serializer\Serializer;$encoders = [newYamlEncoder()];$normalizers = [newObjectNormalizer()];$serializer =newSerializer($normalizers,$encoders);$serializer->deserialize('[1','stdClass','yaml');// throws Symfony\Component\Yaml\Exception\ParseException |
PHPStan has two mode about the exceptions (https://phpstan.org/blog/bring-your-exceptions-under-control#what-does-absent-%40throws-above-a-function-mean%3F): By default PHPStan consider that no
Technically, there is already a contract which say "This method is not supposed to throw any exception". And any implementation is breaking this contract. I'm trying to fix/improve the contract. Symfony already rely on the possible exception thrown since some are caught in the SerializerErrorEncoder, even ifnone is documented symfony/src/Symfony/Component/ErrorHandler/ErrorRenderer/SerializerErrorRenderer.php Line 66 in4078cb1
A better documentation would lead to a better try/catch.
Currently the interface is wrongly informing that no exception are thrown. |
The issue is not about the SerializerInterface contract but about the YamlEncoder whichalready does not respect the EncoderInterface contract.
This YamlEncoder was introduced in Symfony 3 while the So I would think the YamlEncoder need to be fixed. |
SerializerInterface
exceptions…tLanglet)This PR was merged into the 6.4 branch.Discussion----------[Serializer] Fix exception thrown by `YamlEncoder`| Q | A| ------------- | ---| Branch? | 6.4| Bug fix? | yes| New feature? | no| Deprecations? | no| Issues | Fix the example given#59306 (comment)| License | MITDecoderInterface::decode is supposed to throw scoped exception cfhttps://github.com/symfony/symfony/blob/4078cb1642332cf5bbd45f5118edf766580cfb1e/src/Symfony/Component/Serializer/Encoder/DecoderInterface.php#L33-L35but the YamlEncoder::decode could throw ParseException.Others similar Encoder, like XmlEncoder or JsonEncoder are throwing NotEncodableValue so I did the same cf examplehttps://github.com/symfony/symfony/blob/da155534524f0d9c501023d10bb423fce4cd4482/src/Symfony/Component/Serializer/Encoder/JsonEncode.php#L41-L45Commits-------ab9de2d Fix exception thrown by YamlEncoder
That is certainly not what this annotation is about. Exceptions are for cases where something unexpected happens. In some cases, they're for signaling rare situations that shouldn't happen but can happen (the unhappy path). So to me: |
I tried doing better by adding
Would it be ok like this or should I be more explicit@nicolas-grekas ? |
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.
LGTM, here are some more comments and that would be good on my side.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
121e67d
toa6aeb65
CompareThank you@VincentLanglet. |
cdc1101
intosymfony:7.3Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.
This
SerializerInterface::serialize can throws
Since it might be a lot of exception and there is no real need to list them all, I simplified with
@throws ExceptionInterface
.