-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Messenger] Symfony Serializer: Cannot create instance of BusNameStamp #31490
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
Comments
Hmm. Weren’t you having success serializing and deserializing messages for other issues you created? Indeed, I agree that this is odd. I thought that because the constructor arg is “$busName” and the key is “busName” in JSON, that it would know to construct it using that key. Many other stamps follow this convention and I believe are serializing and deserializing fine. I remember even testing the full process using the Symfony serializer a few days ago. Is there any other special setup you have? |
No special setup, the same that I used for the other issues. |
The issue should be gone after running We could probably improve DX by detecting that it is not available before trying to serialize the stamp, and throw a meaningful exception (could even be thrown at compile-time if the symfony serializer is configured on a transport but property-access is not installed). Or we could "hardcode" a special case for the BusNameStamp in the Serializer e.g: foreach ($allStamps as $class => $stamps) {
if (BusNameStamp::class === $class && $stamps) {
$stamps = array_map(function (BusNameStamp $stamp): array { return ['busName' => $stamp->getBusName()]; }, $stamps);
$headers[self::STAMP_HEADER_PREFIX.$class] = $this->serializer->encode([$stamps]);
continue;
}
# ...
} But I guess it wouldn't be very scalable. |
Ah! Wait, so if property access isn’t available, object normalizer isn’t available? What normalizer is used then? Or is it just that his normalizer is less powerful? Anyways, if I understand correctly, pretty much none of the core stamps are serializable with the Symfony serializer unless property access is available as many have constructor arguments without setters, which I think is what works only with property access. I think we should throw an exception in the Symfony serializer for messenger that property access is required if not installed. |
Yes!
Here is the full list of default norsmalizers injected in the
Which obviously don't support normalization for any other type than the one they are prefixed by. But actually, the error I get is not exactly the same as the one described here (which I can't manage to reproduce). Mine is:
So we still need @raresserban to confirm that my solution also fixes his issue, but I think it won't as the stamp is properly normalized but not denormalized. @raresserban Can you please run the command with |
Hello, I have the property-access component, so I don't think the problem is related to yours. Here is the stack trace:
I also updated the apps to 4.3-beta2, but still the same problem... |
I think I found the problem, it is because the name of the constructor argument is not correct. The And if publishing from the same ApiPlatform app with SF 4.2, it works because the constructor variable on line 468 of AbstractNormalizer is null. Also, the nameConverter injected in the AbstractNormalizer class is After further debugging, I think the problem is in the |
Finally found the issue, it was because of a configuration option set in one of our internal bundles. There we set the serializer name converter to be the CamelCaseToSnakeCaseNameConverter for some weird reason, and that bundle was only used in the consuming application, so the publishing app was not affected by it. Also publishing from SF 4.2 was not affected since there the BusNameStamp is not serialized in the envelope... So finally fixed this by setting this in the framework config:
Closing this ticket now. |
This PR was merged into the 4.2 branch. Discussion ---------- [Serializer] Use pack to install As [here](symfony/symfony#31490 (comment)), I also ran into issues using messenger with the Symfony Serializer, due to `symfony/property-access` missing and the `ObjectNormalizer` not being available due to that. This change updates the docs to use the pack instead of the package to install the Serializer (which includes `symfony/property-access`). ~I also included a note for developers that already installed the Serializer directly and try to figure out why `ObjectNormalizer` wasn't available.~ Commits ------- 1ffc677 [Serializer] Use pack to install
I know it is old issue but I encountered the same error message and thought it is worth to put my comment here for the future. In my case I have installed Symfony Serializer compontent as |
@chalasr This is still a problem, The issue is When denormalizing it again, it is unable to map The fix would be to rename the ctor parameter to |
I'll try create another issue/PR with a reproducer. The fix is simple. |
| Q | A | ------------- | --- | Branch? | 6.2 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | symfony#31490 (comment) | License | MIT | Doc PR | n/a Currently, when ones use `TransportNameStamp` the following exception occurs: ``` In Serializer.php line 125: [Symfony\Component\Messenger\Exception\MessageDecodingFailedException] Could not decode stamp: Cannot create an instance of "Symfony\Component\Messenger\Stamp\TransportNamesStamp" from serialized data because its constructor requires parameter "transports" to be present. In AbstractNormalizer.php line 384: [Symfony\Component\Serializer\Exception\MissingConstructorArgumentsException] Cannot create an instance of "Symfony\Component\Messenger\Stamp\TransportNamesStamp" from serialized data because its constructor requires parameter "transports" to be present. ``` This PR renames `TransportNamesStamp` constructor argument in order to match the accesor method (`getTranspdortNames`) so that deserialization work. I know this is technically a BC break but as far as I can tell the feature can not currently work this way and also named arguments are not covered by Symfony's BC if I remember correctly.
…ksaun) This PR was merged into the 6.2 branch. Discussion ---------- [Messenger] Fix `TransportNamesStamp` deserialization | Q | A | ------------- | --- | Branch? | 6.2 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | #49574, #31490 (comment) | License | MIT | Doc PR | n/a Currently, when ones use `TransportNameStamp` the following exception can occur if they don't use native PHP serialization: ``` In Serializer.php line 125: [Symfony\Component\Messenger\Exception\MessageDecodingFailedException] Could not decode stamp: Cannot create an instance of "Symfony\Component\Messenger\Stamp\TransportNamesStamp" from serialized data because its constructor requires parameter "transports" to be present. In AbstractNormalizer.php line 384: [Symfony\Component\Serializer\Exception\MissingConstructorArgumentsException] Cannot create an instance of "Symfony\Component\Messenger\Stamp\TransportNamesStamp" from serialized data because its constructor requires parameter "transports" to be present. ``` This PR renames `TransportNamesStamp` constructor argument in order to match the accessor method (`getTransportNames`) so that deserialization works when using the Serializer. I know this is technically a (small) BC break but Symfony's BC does not cover named arguments if I remember correctly. Commits ------- 2c7eee0 [Messenger] Fix TransportNamesStamp deserialization
| Q | A | ------------- | --- | Branch? | 6.2 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | symfony/symfony#31490 (comment) | License | MIT | Doc PR | n/a Currently, when ones use `TransportNameStamp` the following exception occurs: ``` In Serializer.php line 125: [Symfony\Component\Messenger\Exception\MessageDecodingFailedException] Could not decode stamp: Cannot create an instance of "Symfony\Component\Messenger\Stamp\TransportNamesStamp" from serialized data because its constructor requires parameter "transports" to be present. In AbstractNormalizer.php line 384: [Symfony\Component\Serializer\Exception\MissingConstructorArgumentsException] Cannot create an instance of "Symfony\Component\Messenger\Stamp\TransportNamesStamp" from serialized data because its constructor requires parameter "transports" to be present. ``` This PR renames `TransportNamesStamp` constructor argument in order to match the accesor method (`getTranspdortNames`) so that deserialization work. I know this is technically a BC break but as far as I can tell the feature can not currently work this way and also named arguments are not covered by Symfony's BC if I remember correctly.
Symfony version(s) affected: 4.3-beta1
Description
The exact error that I receive from the console:
Cannot create an instance of Symfony\Component\Messenger\Stamp\BusNameStamp from serialized data because its constructor requires parameter "busName" to be present.
To me this error makes no sens, I have published a message using a SF 4.3 application and tried to consume it in another SF 4.3 application. For some reason the deserialization of the BusNameStamp fails in Symfony\Component\Messenger\Transport\Serialization\Serializer class in the
decodeStamps
function, which really makes no sense since the JSON that is used for the deserialization of this stamp is this:[{"busName":"messenger.bus.default"}]
How to reproduce
Publish a message from a SF 4.3 application using the
messenger.transport.symfony_serializer
service as the messenger default serializer and then try to consume it.The text was updated successfully, but these errors were encountered: