Skip to content
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

Type error in UnionHandler #1566

Open
dmaicher opened this issue Nov 6, 2024 · 9 comments
Open

Type error in UnionHandler #1566

dmaicher opened this issue Nov 6, 2024 · 9 comments
Labels
Union Types Support for Union Types

Comments

@dmaicher
Copy link

dmaicher commented Nov 6, 2024

Q A
Bug report? yes
Feature request? yeso
BC Break report? yes
RFC? no

Steps required to reproduce the problem

jms/serializer        3.31.1 Library for (de-)serializing data of any complexity; supports XML, and JSON.
jms/serializer-bundle 5.5.1  Allows you to easily serialize, and deserialize data of any complexity
$serializer = SerializerBuilder::create()->build();
$serializer->serialize(new class() {
    public array|int $foo = [1, 2, 3];
}, 'json');

Expected Result

  • Should work fine

Actual Result

TypeError:
get_class(): Argument #1 ($object) must be of type object, array given

  at vendor/jms/serializer/src/Handler/UnionHandler.php:56
@scyzoryck
Copy link
Collaborator

It looks like arrays are not supported in current implementation at all. I will take a look at it. Looks like @simPod already started some work around that.
#1552

@mermshaus
Copy link

mermshaus commented Nov 11, 2024

I can confirm this issue. Unfortunately, it breaks existing code. For the time being, we had to pin jms/serializer to v3.30.0 because of this. It might be a good idea to release a new version reverting these changes until the feature supports arrays. (Or, as I see the issue with that, to specify a workaround for disabling the new feature.)

#1552 isn’t working on this, I think. The MR is about “unions” (not really) in arrays, not arrays in unions.

@goetas
Copy link
Collaborator

goetas commented Nov 12, 2024

Unfortunately, it breaks existing code

@scyzoryck would it make sense to revert the union types thing that is causing this error?

from my understanding, #1546 is the guilty one, right?

@scyzoryck
Copy link
Collaborator

We also I think have 2 MRs on top of #1546 so it might need some additional reverts. As an example: #1563
Current issues with Union Types:

  • High prio: Support for true and false types. MR: Support value types in serialization #1569 - we need to add some
  • High prio: Support for array type - I believe I can finish the basic support (fix the issue from this issue), feat: support unions in arrays #1552 may add complex types later.
  • Medium/Low prio: It looks like there might be some issues with DepthExclusionStrategy for Union types, but I guess it was not working in the past at all.

Soo, personally I would go with fixing the issues, and going with the fix release this week with support for missing types.

@goetas
Copy link
Collaborator

goetas commented Nov 14, 2024

Soo, personally I would go with fixing the issues, and going with the fix release this week with support for missing types.

👍

@scyzoryck
Copy link
Collaborator

@dmaicher could you test newest dev-master version, please? :) If it will look good for you I will make the new fix release.

@scyzoryck scyzoryck added the Union Types Support for Union Types label Dec 3, 2024
@dmaicher
Copy link
Author

dmaicher commented Dec 4, 2024

@scyzoryck with my example code mentioned in the issue description I get

PHP Warning: Array to string conversion in /var/www/app/symfony/vendor/jms/serializer/src/Handler/UnionHandler.php on line 129

because in my case int is checked first it seems.

Maybe testPrimitive can be adjusted like this

    private function testPrimitive(mixed $data, string $type, string $format): bool
    {
        if ($type === 'array') {
            return is_array($data);
        }

        if (!is_scalar($data)) {
            return false;
        }

        switch ($type) {
            case 'integer':
            case 'int':
                return (string) (int) $data === (string) $data;

            case 'double':
            case 'float':
                return (string) (float) $data === (string) $data;

            case 'bool':
            case 'boolean':
                return (string) (bool) $data === (string) $data;

            case 'string':
                return is_string($data);
        }

        return false;
    }

Then the warning is gone in my case.

Another issue I noticed:

If I change my property to public array|int|string $foo with string value "666" then its serialized into an integer {"foo":666}. Should be {"foo":"666"} though?

@scyzoryck
Copy link
Collaborator

Sooo, it looks like we need a bit more development on Unions.

I would propose the next steps:

  • add enableUnionSupport method similar to add enableEnumSupport - to bring back the state from the 3.30.x as a default one
  • continue work on the UnionSupport as a experimental one.

@goetas does it sounds good for you?

If I change my property to public array|int|string $foo with string value "666" then its serialized into an integer {"foo":666}. Should be {"foo":"666"} though?

Yes, I think you are right. I think we have "type recognition" logic to determine the correct type - soo "666" is parsed as 666 during both - serialization and deserialization at the moment. So it seems to be similar issue as #1573 #1575 - FYI @fabianerni

IMO we should have the following logic for the type choosing:

Serialization:

  • Keep the types all the time

Deserialization:

  • If the type is supported - keep the type - as example: "666" will be kept as string
  • If the type is not supported - try to guess the type - as example: if property do not support string, but it supports int|bool "1" will be deserialized as int.

@goetas
Copy link
Collaborator

goetas commented Dec 5, 2024

@scyzoryck adding enableUnionSupport makes sense, it seems that there is much more work than expected to have it working properly.

It would be good to revert schmittjoh/JMSSerializerBundle#954 as well

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Union Types Support for Union Types
Projects
None yet
Development

No branches or pull requests

4 participants