pimcore / data-hub

Data delivery & consumption platform for Pimcore.
Other
124 stars 105 forks source link

[Bug]: DataHub not working in test Env #836

Open dpfaffenbauer opened 5 months ago

dpfaffenbauer commented 5 months ago

Expected behavior

should wortk

Actual behavior

not working

Steps to reproduce

run it in test env and you see:

{
  "errors": [
    {
      "message": "Schema must contain unique named types but contains multiple types named \"document_email\" (see https://webonyx.github.io/graphql-php/type-definitions/#type-registry)."
    }
  ]
}

It comes down the following:

I didn't really quite understand why this service is instantiated twice and why it works when its inlined. here is the GraphQlService from inlined vs not:

Not Inlined:

        $d = new \Pimcore\Bundle\DataHubBundle\GraphQL\DocumentType\DocumentType($instance, ($container->privates['Pimcore\\Bundle\\DataHubBundle\\GraphQL\\DocumentType\\PageType'] ?? $container->load('getPageTypeService')), ($container->privates['Pimcore\\Bundle\\DataHubBundle\\GraphQL\\DocumentType\\LinkType'] ?? $container->load('getLinkTypeService')), ($container->privates['Pimcore\\Bundle\\DataHubBundle\\GraphQL\\DocumentType\\EmailType'] ?? $container->load('getEmailTypeService')), ($container->privates['Pimcore\\Bundle\\DataHubBundle\\GraphQL\\DocumentType\\HardlinkType'] ?? $container->load('getHardlinkTypeService')), ($container->privates['Pimcore\\Bundle\\DataHubBundle\\GraphQL\\DocumentType\\SnippetType'] ?? $container->load('getSnippetTypeService')));
        $d->registerCustomDataType([]);
        $e = ($container->privates['Pimcore\\Bundle\\DataHubBundle\\GraphQL\\DocumentType\\DocumentElementType'] ?? $container->load('getDocumentElementTypeService'));

        $instance->setSupportedGeneralTypes([]);
        $instance->setSupportedDataObjectQueryDataTypes(['coreShopDynamicDropdown', 'coreShopRelation', 'coreShopDynamicDropdownMultiple', 'coreShopItemSelector', 'coreShopSuperBoxSelect', 'coreShopSerializedData', 'coreShopRelations', 'coreShopMoney', 'coreShopCartPriceRule', 'coreShopProductSpecificPriceRules', 'coreShopProductUnit', 'coreShopProductUnitDefinition', 'coreShopProductUnitDefinitions', 'coreShopCountry', 'coreShopState', 'coreShopAddressIdentifier', 'coreShopCountryMultiselect', 'coreShopCurrency', 'coreShopCurrencyMultiselect', 'coreShopMoneyCurrency', 'coreShopTaxRuleGroup', 'coreShopStore', 'coreShopStoreMultiselect', 'coreShopFilter', 'coreShopCarrier', 'coreShopCarrierMultiselect', 'coreShopPaymentProvider', 'coreShopProductQuantityPriceRules', 'coreShopStoreValues', 'booleanSelect', 'checkbox', 'newsletterActive', 'newsletterConfirmed', 'classificationstore', 'date', 'datetime', 'email', 'href', 'manyToOneRelation', 'fieldcollections', 'firstname', 'geobounds', 'geopolygon', 'geopoint', 'hotspotimage', 'image', 'imageGallery', 'link', 'externalImage', 'input', 'rgbaColor', 'time', 'calculatedValue', 'lastname', 'multihref', 'manyToManyRelation', 'manyToManyObjectRelation', 'reverseManyToManyObjectRelation', 'reverseObjectRelation', 'multihrefMetadata', 'advancedManyToManyRelation', 'advancedManyToManyObjectRelation', 'languagemultiselect', 'multiselect', 'countrymultiselect', 'numeric', 'quantityValue', 'inputQuantityValue', 'country', 'gender', 'language', 'select', 'slider', 'textarea', 'urlSlug', 'video', 'wysiwyg', 'table', 'structuredTable', 'block']);
        $instance->setSupportedDataObjectMutationDataTypes(['coreShopDynamicDropdown', 'coreShopRelations', 'coreShopDynamicDropdownMultiple', 'coreShopItemSelector', 'coreShopSuperBoxSelect', 'booleanSelect', 'checkbox', 'country', 'countrymultiselect', 'date', 'datetime', 'email', 'externalImage', 'fieldcollections', 'geopoint', 'firstname', 'gender', 'input', 'image', 'language', 'lastname', 'newsletterActive', 'manyToOneRelation', 'manyToManyRelation', 'manyToManyObjectRelation', 'advancedManyToManyRelation', 'advancedManyToManyObjectRelation', 'multiselect', 'newsletterConfirmed', 'numeric', 'select', 'slider', 'textarea', 'time', 'wysiwyg', 'quantityValue', 'table', 'imageGallery', 'link']);
        $instance->setSupportedDocumentElementQueryDataTypes(['areablock', 'block', 'checkbox', 'date', 'embed', 'input', 'image', 'link', 'multiselect', 'numeric', 'pdf', 'relation', 'relations', 'scheduledblock', 'select', 'table', 'textarea', 'wysiwyg', 'video']);
        $instance->setSupportedDocumentElementMutationDataTypes(['areablock', 'block', 'embed', 'image', 'input', 'multiselect', 'scheduledblock', 'select', 'wysiwyg']);
        $instance->setSupportedCsFeatureQueryDataTypes(['booleanSelect', 'calculatedValue', 'checkbox', 'country', 'countrymultiselect', 'date', 'datetime', 'input', 'inputQuantityValue', 'language', 'languagemultiselect', 'multiselect', 'numeric', 'rgbaColor', 'select', 'slider', 'textarea', 'time', 'quantityValue', 'wysiwyg']);
        $instance->registerAssetDataTypes(['asset_metadata_item' => new \Pimcore\Bundle\DataHubBundle\GraphQL\AssetType\AssetMetadataItem($instance), 'asset_input' => new \Pimcore\Bundle\DataHubBundle\GraphQL\AssetType\AssetInputType($instance), '_asset_folder' => new \Pimcore\Bundle\DataHubBundle\GraphQL\AssetType\AssetFolderType($instance), 'asset_tree' => new \Pimcore\Bundle\DataHubBundle\GraphQL\AssetType\AssetTreeType($instance)]);
        $instance->registerTranslationDataTypes([]);
        $instance->registerDataObjectDataTypes(['elementdescriptor_input' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DataObjectType\ElementDescriptorInputType($instance), 'geopoint_input' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DataObjectType\GeopointInputType($instance), 'object_tree' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DataObjectType\ObjectTreeType($instance), '_object_folder' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DataObjectType\ObjectFolderType($instance), 'object_datatype_hotspotimage' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DataObjectType\HotspotType($instance), 'manytoone' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DataObjectType\HrefType($instance), 'input_quantity_value' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DataObjectType\InputQuantityValueType($instance), 'quantity_value' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DataObjectType\QuantityValueType($instance), 'url_slug' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DataObjectType\UrlSlugType($instance), 'object_datatype_video' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DataObjectType\VideoType($instance, ($container->privates['Pimcore\\Bundle\\DataHubBundle\\GraphQL\\DataObjectType\\VideoTypeDataType'] ?? $container->load('getVideoTypeDataTypeService'))), 'object_datatype_video_data' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DataObjectType\VideoTypeDataType($instance), 'quantity_value_input' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DataObjectType\QuantityValueInputType($instance), 'link_input' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DataObjectType\LinkInputType($instance), 'image_input' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DataObjectType\InputType\ImageInputType($instance)]);
        $instance->registerDocumentDataTypes(['document' => $d, 'document_tree' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DocumentType\DocumentTreeType($instance), 'document_element' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DocumentType\DocumentElementType($instance), 'document_email' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DocumentType\EmailType($instance), 'document_hardlink' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DocumentType\HardlinkType($instance, ($container->privates['Pimcore\\Bundle\\DataHubBundle\\GraphQL\\General\\AnyDocumentTargetType'] ?? $container->load('getAnyDocumentTargetTypeService'))), 'document_link' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DocumentType\LinkType($instance), 'document_page' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DocumentType\PageType($instance, $e), 'document_snippet' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DocumentType\SnippetType($instance, $e), '_document_folder' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DocumentType\DocumentFolderType($instance), 'document_link_input' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DocumentType\DocumentLinkInputType($instance)]);
        $instance->registerClassificationStoreDataTypes(['cs_group' => new \Pimcore\Bundle\DataHubBundle\GraphQL\ClassificationstoreType\Group($instance, ($container->privates['Pimcore\\Bundle\\DataHubBundle\\GraphQL\\ClassificationstoreType\\Feature'] ?? $container->load('getFeatureService'))), 'cs_feature' => new \Pimcore\Bundle\DataHubBundle\GraphQL\ClassificationstoreType\Feature($instance)]);
        $instance->registerPropertyDataTypes(['elementproperty' => new \Pimcore\Bundle\DataHubBundle\GraphQL\PropertyType\ElementPropertyType($instance), 'hotspotmetadata' => new \Pimcore\Bundle\DataHubBundle\GraphQL\PropertyType\HotspotMetadataType($instance), 'property_asset' => new \Pimcore\Bundle\DataHubBundle\GraphQL\PropertyType\AssetType($instance), 'property_document' => new \Pimcore\Bundle\DataHubBundle\GraphQL\PropertyType\DocumentType($instance), 'property_assetfolder' => new \Pimcore\Bundle\DataHubBundle\GraphQL\PropertyType\AssetFolderType($instance), 'property_documentfolder' => new \Pimcore\Bundle\DataHubBundle\GraphQL\PropertyType\DocumentFolderType($instance), 'property_objectfolder' => new \Pimcore\Bundle\DataHubBundle\GraphQL\PropertyType\ObjectFolderType($instance), 'property_object' => new \Pimcore\Bundle\DataHubBundle\GraphQL\PropertyType\DataObjectType($instance, ($container->privates['Pimcore\\Bundle\\DataHubBundle\\GraphQL\\PropertyType\\ObjectsType'] ?? $container->load('getObjectsTypeService'))), 'property_checkbox' => new \Pimcore\Bundle\DataHubBundle\GraphQL\PropertyType\CheckboxType($instance), 'property_textarea' => new \Pimcore\Bundle\DataHubBundle\GraphQL\PropertyType\TextareaType($instance), 'property_text' => new \Pimcore\Bundle\DataHubBundle\GraphQL\PropertyType\TextType($instance), 'property_select' => new \Pimcore\Bundle\DataHubBundle\GraphQL\PropertyType\SelectType($instance)]);

        return $instance;

Inlined


        $d = new \Pimcore\Bundle\DataHubBundle\GraphQL\DataObjectType\VideoTypeDataType($instance);
        $e = new \Pimcore\Bundle\DataHubBundle\GraphQL\DocumentType\DocumentElementType($instance);

        $f = new \Pimcore\Bundle\DataHubBundle\GraphQL\DocumentType\PageType($instance, $e);
        $g = new \Pimcore\Bundle\DataHubBundle\GraphQL\DocumentType\LinkType($instance);
        $h = new \Pimcore\Bundle\DataHubBundle\GraphQL\DocumentType\EmailType($instance);
        $i = new \Pimcore\Bundle\DataHubBundle\GraphQL\DocumentType\HardlinkType($instance, new \Pimcore\Bundle\DataHubBundle\GraphQL\General\AnyDocumentTargetType($instance));
        $j = new \Pimcore\Bundle\DataHubBundle\GraphQL\DocumentType\SnippetType($instance, $e);

        $k = new \Pimcore\Bundle\DataHubBundle\GraphQL\DocumentType\DocumentType($instance, $f, $g, $h, $i, $j);
        $k->registerCustomDataType([]);
        $l = new \Pimcore\Bundle\DataHubBundle\GraphQL\ClassificationstoreType\Feature($instance);

        $instance->setSupportedGeneralTypes([]);
        $instance->setSupportedDataObjectQueryDataTypes(['coreShopDynamicDropdown', 'coreShopRelation', 'coreShopDynamicDropdownMultiple', 'coreShopItemSelector', 'coreShopSuperBoxSelect', 'coreShopSerializedData', 'coreShopRelations', 'coreShopMoney', 'coreShopCartPriceRule', 'coreShopProductSpecificPriceRules', 'coreShopProductUnit', 'coreShopProductUnitDefinition', 'coreShopProductUnitDefinitions', 'coreShopCountry', 'coreShopState', 'coreShopAddressIdentifier', 'coreShopCountryMultiselect', 'coreShopCurrency', 'coreShopCurrencyMultiselect', 'coreShopMoneyCurrency', 'coreShopTaxRuleGroup', 'coreShopStore', 'coreShopStoreMultiselect', 'coreShopFilter', 'coreShopCarrier', 'coreShopCarrierMultiselect', 'coreShopPaymentProvider', 'coreShopProductQuantityPriceRules', 'coreShopStoreValues', 'booleanSelect', 'checkbox', 'newsletterActive', 'newsletterConfirmed', 'classificationstore', 'date', 'datetime', 'email', 'href', 'manyToOneRelation', 'fieldcollections', 'firstname', 'geobounds', 'geopolygon', 'geopoint', 'hotspotimage', 'image', 'imageGallery', 'link', 'externalImage', 'input', 'rgbaColor', 'time', 'calculatedValue', 'lastname', 'multihref', 'manyToManyRelation', 'manyToManyObjectRelation', 'reverseManyToManyObjectRelation', 'reverseObjectRelation', 'multihrefMetadata', 'advancedManyToManyRelation', 'advancedManyToManyObjectRelation', 'languagemultiselect', 'multiselect', 'countrymultiselect', 'numeric', 'quantityValue', 'inputQuantityValue', 'country', 'gender', 'language', 'select', 'slider', 'textarea', 'urlSlug', 'video', 'wysiwyg', 'table', 'structuredTable', 'block']);
        $instance->setSupportedDataObjectMutationDataTypes(['coreShopDynamicDropdown', 'coreShopRelations', 'coreShopDynamicDropdownMultiple', 'coreShopItemSelector', 'coreShopSuperBoxSelect', 'booleanSelect', 'checkbox', 'country', 'countrymultiselect', 'date', 'datetime', 'email', 'externalImage', 'fieldcollections', 'geopoint', 'firstname', 'gender', 'input', 'image', 'language', 'lastname', 'newsletterActive', 'manyToOneRelation', 'manyToManyRelation', 'manyToManyObjectRelation', 'advancedManyToManyRelation', 'advancedManyToManyObjectRelation', 'multiselect', 'newsletterConfirmed', 'numeric', 'select', 'slider', 'textarea', 'time', 'wysiwyg', 'quantityValue', 'table', 'imageGallery', 'link']);
        $instance->setSupportedDocumentElementQueryDataTypes(['areablock', 'block', 'checkbox', 'date', 'embed', 'input', 'image', 'link', 'multiselect', 'numeric', 'pdf', 'relation', 'relations', 'scheduledblock', 'select', 'table', 'textarea', 'wysiwyg', 'video']);
        $instance->setSupportedDocumentElementMutationDataTypes(['areablock', 'block', 'embed', 'image', 'input', 'multiselect', 'scheduledblock', 'select', 'wysiwyg']);
        $instance->setSupportedCsFeatureQueryDataTypes(['booleanSelect', 'calculatedValue', 'checkbox', 'country', 'countrymultiselect', 'date', 'datetime', 'input', 'inputQuantityValue', 'language', 'languagemultiselect', 'multiselect', 'numeric', 'rgbaColor', 'select', 'slider', 'textarea', 'time', 'quantityValue', 'wysiwyg']);
        $instance->registerAssetDataTypes(['asset_metadata_item' => new \Pimcore\Bundle\DataHubBundle\GraphQL\AssetType\AssetMetadataItem($instance), 'asset_input' => new \Pimcore\Bundle\DataHubBundle\GraphQL\AssetType\AssetInputType($instance), '_asset_folder' => new \Pimcore\Bundle\DataHubBundle\GraphQL\AssetType\AssetFolderType($instance), 'asset_tree' => new \Pimcore\Bundle\DataHubBundle\GraphQL\AssetType\AssetTreeType($instance)]);
        $instance->registerTranslationDataTypes([]);
        $instance->registerDataObjectDataTypes(['elementdescriptor_input' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DataObjectType\ElementDescriptorInputType($instance), 'geopoint_input' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DataObjectType\GeopointInputType($instance), 'object_tree' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DataObjectType\ObjectTreeType($instance), '_object_folder' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DataObjectType\ObjectFolderType($instance), 'object_datatype_hotspotimage' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DataObjectType\HotspotType($instance), 'manytoone' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DataObjectType\HrefType($instance), 'input_quantity_value' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DataObjectType\InputQuantityValueType($instance), 'quantity_value' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DataObjectType\QuantityValueType($instance), 'url_slug' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DataObjectType\UrlSlugType($instance), 'object_datatype_video' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DataObjectType\VideoType($instance, $d), 'object_datatype_video_data' => $d, 'quantity_value_input' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DataObjectType\QuantityValueInputType($instance), 'link_input' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DataObjectType\LinkInputType($instance), 'image_input' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DataObjectType\InputType\ImageInputType($instance)]);
        $instance->registerDocumentDataTypes(['document' => $k, 'document_tree' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DocumentType\DocumentTreeType($instance), 'document_element' => $e, 'document_email' => $h, 'document_hardlink' => $i, 'document_link' => $g, 'document_page' => $f, 'document_snippet' => $j, '_document_folder' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DocumentType\DocumentFolderType($instance), 'document_link_input' => new \Pimcore\Bundle\DataHubBundle\GraphQL\DocumentType\DocumentLinkInputType($instance)]);
        $instance->registerClassificationStoreDataTypes(['cs_group' => new \Pimcore\Bundle\DataHubBundle\GraphQL\ClassificationstoreType\Group($instance, $l), 'cs_feature' => $l]);
        $instance->registerPropertyDataTypes(['elementproperty' => new \Pimcore\Bundle\DataHubBundle\GraphQL\PropertyType\ElementPropertyType($instance), 'hotspotmetadata' => new \Pimcore\Bundle\DataHubBundle\GraphQL\PropertyType\HotspotMetadataType($instance), 'property_asset' => new \Pimcore\Bundle\DataHubBundle\GraphQL\PropertyType\AssetType($instance), 'property_document' => new \Pimcore\Bundle\DataHubBundle\GraphQL\PropertyType\DocumentType($instance), 'property_assetfolder' => new \Pimcore\Bundle\DataHubBundle\GraphQL\PropertyType\AssetFolderType($instance), 'property_documentfolder' => new \Pimcore\Bundle\DataHubBundle\GraphQL\PropertyType\DocumentFolderType($instance), 'property_objectfolder' => new \Pimcore\Bundle\DataHubBundle\GraphQL\PropertyType\ObjectFolderType($instance), 'property_object' => new \Pimcore\Bundle\DataHubBundle\GraphQL\PropertyType\DataObjectType($instance, new \Pimcore\Bundle\DataHubBundle\GraphQL\PropertyType\ObjectsType($instance)), 'property_checkbox' => new \Pimcore\Bundle\DataHubBundle\GraphQL\PropertyType\CheckboxType($instance), 'property_textarea' => new \Pimcore\Bundle\DataHubBundle\GraphQL\PropertyType\TextareaType($instance), 'property_text' => new \Pimcore\Bundle\DataHubBundle\GraphQL\PropertyType\TextType($instance), 'property_select' => new \Pimcore\Bundle\DataHubBundle\GraphQL\PropertyType\SelectType($instance)]);

        $c->setGraphQlService($instance);

        $b->setGraphQlService($instance);

        $a->setGraphQlService($instance);

        return $instance;

You can see that the EmailType get's instantiated twice, in both cases. But I did not understand why one works and the other doesn't. Anyhow: That service should always only get instantiated once anyway. So there is an issue with the service declaration somewhere.

ibousfiha commented 5 months ago

Thank you for reporting this. Can you please provide more details on how to reproduce? Are you running a specific test or a query?

dpfaffenbauer commented 5 months ago

Run in test env and try to execute any query.

ibousfiha commented 5 months ago

Unfortunately I couldn't reproduce, it would be helpful if you could provide more insights.

dpfaffenbauer commented 5 months ago

what happens if you enable this for you:

framework:
    test: false
dpfaffenbauer commented 5 months ago

I've just checked again, it doesn't do that for an out-of-the box setup.

We added our own datahub provider that extends the graphql one. Basically allowing us to add custom configs and modify the query set. It only happens when you do that.

If you are interested, I can give you access to the repo. It's private.

dpfaffenbauer commented 5 months ago

not true, after further investigation, it also happens without my bundle when using a graphql config with documents enabled and framework.test enabled.

this config fails for me:

pimcore_data_hub:
    configurations:
        test:
            general:
                active: true
                type: graphql
                name: test
                description: ''
                group: ''
                sqlObjectCondition: ''
                modificationDate: 1708453670
                path: null
                createDate: 1708453186
            schema:
                queryEntities: { }
                mutationEntities: {  }
                specialEntities:
                    document:
                        read: true
                        create: false
                        update: false
                        delete: false
                    document_folder:
                        read: false
                        create: false
                        update: false
                        delete: false
                    asset:
                        read: true
                        create: false
                        update: false
                        delete: false
                    asset_folder:
                        read: false
                        create: false
                        update: false
                        delete: false
                    asset_listing:
                        read: false
                        create: false
                        update: false
                        delete: false
                    object_folder:
                        read: false
                        create: false
                        update: false
                        delete: false
                    translation:
                        read: false
                        create: false
                        update: false
                        delete: false
                    translation_listing:
                        read: false
                        create: false
                        update: false
                        delete: false
                    coreshop_frontend:
                        read: true
                        create: false
                        update: false
                        delete: false
            security:
                method: datahub_apikey
                apikey:
                    - f3025c050b6e7934c33a737a2ab5069d
                skipPermissionCheck: false
                disableIntrospection: false
            workspaces:
                asset: {  }
                document: {  }
                object:
                    -
                        read: true
                        cpath: /
                        create: false
                        update: false
                        delete: false
                        id: extModel1438-1
            permissions:
                user: {  }
                role: {  }
kingjia90 commented 5 months ago

Thank you, could reproduce it (beside that the workspace rule here should be assigned document instead of object image)

and dug a little bit but don't know how to fix it, it seems that when framework.test is set, it tries to get service instantiated each time (for testing purposes i guess, more practical with mock services?)

dpfaffenbauer commented 5 months ago

@kingjia90 Its a test setup, so config might be messed up due to testing ;)

I also don't know what is going on... But whatever it is, it should be fixed. It makes it quite uncomfortable to test with data-hub with these weird issues.

fashxp commented 5 months ago

Did that emerge recently, or has it always been that way? Maybe related? https://github.com/pimcore/pimcore/pull/16582

dpfaffenbauer commented 5 months ago

no idea

dkarlovi commented 5 months ago

I was just about to report this issue for object_folder.

We had this issue before, it's due to the fact the type map is kept around between (test) requests, but the type objects are created again and again, I'm not sure exactly why that is.

We've workaround it by doing something like this


private static ?InputObjectType $type = null;

public function getGraphQlMutationOperatorConfig($nodeDef, $class = null, $container = null, $params = []): array
{
        return [
            'arg' => ['type' => Type::listOf(self::$type ??= new InputObjectType([
            // etc...

Since the instance of the type is kept around somewhere and then the type map is checked for name and instance in \GraphQL\Utils\TypeInfo::extractTypes, this basically keeps the same type around instead of creating a new instance (which will not pass the check).

We had this issue even with regular use, not just in tests, if the same operator was assigned multiple times.

jonathan-dejong commented 2 months ago

Hi! Chiming in here as we're seeing this exact error happening spontaneously with the latest PImcore and Data-hub bundle install.

  "errors": [
    {
      "message": "Schema must contain unique named types but contains multiple types named \"document_email\" (see https://webonyx.github.io/graphql-php/type-definitions/#type-registry)."
    }
  ]
}

I've yet to find out exactly why, but it only happens whenever I spread an object in the query. It doesn't matter what object. I've managed to get it by spreading the parent/children, a field collection and imageGallery/hotspotimage objects.

For example:

imageGallery {
          ...on hotspotimage{
                    image{
              id
                      fullpath
                    }
                  }
        }

Or field collection:

StockStatus {
          ...on fieldcollection_StockStatus{
            StockStatus
            SoldIndividually
            Sites
          }
        }

However I do not have documents set for the query at all. Screenshot 2024-05-15 at 14 30 22

It appears to be triggered at random, possibly when making changes to the Query Schema but I've had a hard time verifying that.

This is a really bad failure for the stability of the API so I'm hoping it can be resolved. I've no confidence it will be stable and run in production at the moment 😬 As such, I'm happy to help however I can, with the disclaimer that I know next to nothing of the core code of Pimcore and DataHub @kingjia90 .

dkarlovi commented 2 months ago

It's not triggered at random, the cause of this is, as I've noted before, the same type is used twice (two different uses), but the type map has a reference only to the first one.

For example, if you have a type called say foo, it will check the type map and store

map['foo'] = fooInstance

When foo is used again, it will (for some reason, that's the bug here IMO?) create the fooInstance again and then check it, if it exists in the map and if it's the same instance. It's not the same instance, so it fails, even though both instances can be identical otherwise.

The offending line: https://github.com/webonyx/graphql-php/blob/9f1868d27d4a1bc6e9829a7b827023c52c1d932f/src/Utils/TypeInfo.php#L111

The workaround is to make all the Pimcore types singletons as I've shown in the previous comment, but the actual fix is to disallow creating the same type twice at all.

jonathan-dejong commented 2 months ago

@dkarlovi What I meant by "random" is that there are no apparent reason this error occurs in my instance. I can literally have the exact same schema setup and run the exact same GraphQL query (NOT adding same instance twice) and produce the error.

I am not using PHP to set this up, I'm using the Pimcore datahub GUI. I could replicate the error by just adding ONE field request for a spread object like in the examples I posted.

But then the exact same query would start working later, without making any apparent changes to it. It kept happening the other day.. right now I can't seem to replicate it.

What is the defining factor that causes this to happen specifically for the internal document type of email then? I understand that there's a difference in the code as displayed by the OP but I've not made any changes to my instance between when it works and when it throws that specific error.

jonathan-dejong commented 2 months ago

Update: Okay this is interesting. I've not changed anything in the codebase, I've not changed the query. After doing an deploy of the pimcore repository we have running, the error reappeared after things having worked without issues for days. Here's my current query:

query {
  getProductSimpleListing {
    edges {
      node {
        id
        Title
        isSynced
        SKU
        GTIN8
        GTIN12
        GTIN13
        GTIN14
        ISBN
        MPN
        parent{
            ...on object_ProductSimple{
            id
          }  
        }
        imageGallery {
          ...on hotspotimage{
                    image{
              id
                      fullpath
                    }
                  }
        }
        StockStatus {
          ...on fieldcollection_StockStatus{
            StockStatus
            SoldIndividually
            Sites
          }
        }
        Description
        Excerpt
        ProductSites
        MenuOrder
        EnableReviews
        PurchaseNote
        tags {
          id
          name
        }
        creationDate
        modificationDate
      }
    }
  }
}

Which produces the error:

Schema must contain unique named types but contains multiple types named \"document_email\" (see https://webonyx.github.io/graphql-php/type-definitions/#type-registry).

The deploy clear caches for example, I can share what it does in more details if that would be relevant. However I cleared caches manually last week without the error occurring so I don't think that relates.

I can get the error removed if I remove all my spread data in the query. So this one works (but I have to remove ALL spread data):

query {
  getProductSimpleListing {
    edges {
      node {
        id
        Title
        isSynced
        SKU
        GTIN8
        GTIN12
        GTIN13
        GTIN14
        ISBN
        MPN
        Description
        Excerpt
        ProductSites
        MenuOrder
        EnableReviews
        PurchaseNote
        tags {
          id
          name
        }
        creationDate
        modificationDate
      }
    }
  }
}

Once the error started to occur again this error pops up in the playground: error.log

middleware.js:98 Uncaught Error: {
  "errors": [
    {
      "message": "Internal server error",
      "locations": [
        {
          "line": 12,
          "column": 5
        }
      ],
      "path": [
        "__schema",
        "types"
      ]
    }
  ]
}
    at Object.next (middleware.js:98:43578)
    at b (middleware.js:98:5893)
    at E (middleware.js:98:6399)
    at e.value (middleware.js:98:6952)
    at middleware.js:124:179565

and the schema is not possible to load. Expanding that tab merely keeps it "loading" infinitely. I suppose due to the JS error since it's occuring in the e.prototype.fetchSchema function.
this is used to fetch the introspection stuff.

Now, if I disable introspection for my endpoint, I instead get this error:

middleware.js:98 Uncaught Error: {
  "errors": [
    {
      "message": "GraphQL introspection is not allowed, but the query contained __schema or __type",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ]
    }
  ]
}
    at Object.next (middleware.js:98:43578)

Which is also interesting because afaik my query does not contain __schema or __type. Or is simply querying a listing defined as such? Worth noting though that it doesn't matter if I change from listing to just get one item. Note that this is the same error location, just a different error. So it seems it's still trying to load the schema and failing.

So far, things I've tested to see if I can get the error removed again:

EDIT: I should probably also say that there's two different things here.. so as to not cause confusion (and maybe I should make a separate issue?). The above JS error and schema loading issue is not the same issue as the query not working when using a spread object.

I can still get a result from the playground if I remove the spread objects even with the schema errors.

jonathan-dejong commented 2 months ago

Can anyone please at least help me with how I can circumvent this issue in the meantime? @kingjia90 It would be very kind as I'm not sure how to go about doing so.. I can't find the location where OP points out to be an issue and I'm not sure how your hotfix should be implemented @dkarlovi ?

I'm happy to patch whatever I need, I know my way around PHP, just not the vast Pimcore codebase or ecosystem as I just started my first project with it 😅

Right now I'm severely crippled by this error:

{
  "errors": [
    {
      "message": "Schema must contain unique named types but contains multiple types named \"document_email\" (see https://webonyx.github.io/graphql-php/type-definitions/#type-registry)."
    }
  ]
}

As it means I cannot spread any object in my graphQL, not even getting imageGallery or parent objects ids.

Thank you in advance

kingjia90 commented 2 months ago

@jonathan-dejong Thank you for having a look and for the detailed info.

Unfortunately, I was also stuck and i currently don't have any tips/suggestions on how to workaround it, besides to not using the TEST env.

I will have a deeper look in what you have already researched and posted to see if i get some more clues on how it could be solved, but it may take some time.

jonathan-dejong commented 2 months ago

@kingjia90 Thanks, I'm not sure what constitutes as using the test env 🤔
I've checked my config.yml file for the pimcore setup but I'm not setting that as a test environment under the "framework" (it's actually empty, I don't set anything there).

So just wondering if you can maybe help me in how I can ensure that test mode is definitely not turned on? 🙇

dkarlovi commented 2 months ago

This issue is unrelated to the test env, even though it's more likely to get triggered in the test env.

jonathan-dejong commented 2 months ago

At least I figured out that we were setting APP_ENV to test which seems to be equal to framework.test. Changing that seems to have removed the error for now on my own environment thankfully.

khenow1978 commented 1 month ago

Hi.. I'm facing the same problem and can't find a proper work around. I tested the app_env settings and yes.. it works if I change the value from test to dev.. Only problem here is that my dev config is different from the test config (links to settings, etc.). That's why I can't really use this approach.

Are there any other options? I've noticed that the issue appears after I added specific fields to the GraphQL definition.

Any help would be appreciated.