doctrine / orm

Doctrine Object Relational Mapper (ORM)
https://www.doctrine-project.org/projects/orm.html
MIT License
9.86k stars 2.5k forks source link

Calling method on null when non-backed Enums are used #11173

Open thePanz opened 5 months ago

thePanz commented 5 months ago

Bug Report

Q A
BC Break no
Version 2.17.3

Summary

When non-backed enums are used, an error occurs: Call to a member function getName() on null.

I know that only backed enums are supported, but guiding the developer to fix the issue in an error message should be implemented.

Current behavior

Running bin/console doctrine:mapping:info throws

In DefaultTypedFieldMapper.php line 67:

  [Error]                                      
  Call to a member function getName() on null                                             

Exception trace:
  at /www/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/DefaultTypedFieldMapper.php:67
 Doctrine\ORM\Mapping\DefaultTypedFieldMapper->validateAndComplete() at /www/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php:1594
 Doctrine\ORM\Mapping\ClassMetadataInfo->validateAndCompleteTypedFieldMapping() at /www/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php:1644
 Doctrine\ORM\Mapping\ClassMetadataInfo->validateAndCompleteFieldMapping() at /www/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/ClassMetadataInfo.php:2727
[...]

How to reproduce

Use the following classes. Notes:

enum Suit {
    case Hearts;
    case Diamonds;
    case Clubs;
    case Spades;
}

#[Entity]
class Card
{
    /** ... */

    #[Column(enumType: Suit::class)]
    public Suit $suit;
}

Expected behavior

An error message about using a Backed enum should be reported for better DX

I would suggest some changes as to throw an exception in case the enum is not backed, stating which enum is used and in which class and property the error occurred.

    public function validateAndComplete(array $mapping, ReflectionProperty $field): array
    {
        $type = $field->getType();

        if (
            ! isset($mapping['type'])
            && ($type instanceof ReflectionNamedType)
        ) {
            if (PHP_VERSION_ID >= 80100 && ! $type->isBuiltin() && enum_exists($type->getName())) {
                $mapping['enumType'] = $type->getName();

                $reflection = new ReflectionEnum($type->getName());
                // <-- here!
                if (!$reflection->isBacked()) {
                    throw MappingException::notBackedEnum();
                }
                $type       = $reflection->getBackingType();

                assert($type instanceof ReflectionNamedType);
            }

            if (isset($this->typedFieldMappings[$type->getName()])) {
                $mapping['type'] = $this->typedFieldMappings[$type->getName()];
            }
        }

        return $mapping;
    }

Note: I would create a PR myself, but cloning the repo gives me a GIT error, sorry :(

$ git clone git@github.com:doctrine/orm.git

Cloning into 'orm'...
remote: Enumerating objects: 183294, done.
remote: Counting objects: 100% (2025/2025), done.
remote: Compressing objects: 100% (641/641), done.
error: object 3c45ee692037350ffe3b20565bdff0952f60dbd6: zeroPaddedFilemode: contains zero-padded file modes
fatal: fsck error in packed object
fatal: fetch-pack: invalid index-pack output
greg0ire commented 5 months ago

Note: I would create a PR myself, but cloning the repo gives me a GIT error, sorry :(

:exploding_head:

I don't reproduce this issue:

$ git clone git@github.com:doctrine/orm.git
Cloning into 'orm'...
remote: Enumerating objects: 183294, done.
remote: Counting objects: 100% (2024/2024), done.
remote: Compressing objects: 100% (642/642), done.
remote: Total 183294 (delta 1312), reused 1804 (delta 1181), pack-reused 181270
Receiving objects: 100% (183294/183294), 50.32 MiB | 5.95 MiB/s, done.
Resolving deltas: 100% (131067/131067), done.

My output is slightly different, I'm getting one less object, and compressing more :thinking:

$ git cat-file -t 3c45ee692037350ffe3b20565bdff0952f60dbd6
tree
$ git cat-file -p 3c45ee692037350ffe3b20565bdff0952f60dbd6
040000 tree 6474aaa0ab3abba2492484a8c433712c5224f555    cookbook
040000 tree 97e113ae4df26334a247dd18a0bf51d885ec4d87    manual

040000 maybe that's the zero-padded file mode? What version of git are you using?

thePanz commented 5 months ago

040000 maybe that's the zero-padded file mode? What version of git are you using? I am using git version 2.43.0 under Linux (this is the first time I get such error) :shrug:

greg0ire commented 5 months ago

Same version here, also on Linux so at least it's not that.

greg0ire commented 5 months ago

@thePanz do you maybe have such settings set to true: https://stackoverflow.com/q/41029654/353612 ?

I managed to reproduce your issue with

$ git clone --config transfer.fsckobjects=true \
   --config receive.fsckobjects=true \
   --config fetch.fsckobjects=true \
   git@github.com:doctrine/orm.git doctrine-orm