FieldEntityReference resolver loads invalid translations.

Created on 4 February 2025, 4 months ago

Problem/Motivation

We have a site with default language of ES-ES. We have a multi-value entity reference field on nodes that reference taxonomy terms. We have a fragment for the entity reference that uses the 'name' of the term and we keep getting an error on requests for certain field values: Cannot return null for non-nullable field "TermTag.name"

We have discovered that one of the terms that the node is referencing was not created in the site default language. The error goes away if we create the missing translation but there is still a problem with graphql because it should fallback to the current entity rather than trying to load a translation that doesn't exist. Note, that this error ONLY happens on requests as its unable to fulfill the 'name' property for the fragment since the proper entity is not actually being returned. I've found that the underlying problem is in the data producer which is using this function from graphql module: https://git.drupalcode.org/project/graphql_compose/-/blob/2.3.x/src/Plug.... That function is incorrectly returning the wrong object with the current language logic.

Steps to reproduce

  1. Create a site with multiple languages.
  2. Create a taxonomy (e.g. tags) with a few terms in it with default language.
  3. Add another term with language NOT using the default language and do not add any other translations.
  4. Add multi-value entity reference field on node (e.g. the default article type will work) referencing the tags taxonomy.
  5. Add a node in default language referencing some terms (in particular include the one that does NOT have translation in default site language).
  6. On the frontend, query for the node using a fragment on the taxonomy field.
  7. This is where the query fails and returns the above error

Proposed resolution

Since the getTranslated() method is borrowed from graphql module, I propose bypass even using it as we are already looping over the referenced entities and can compare the language passed to producer with the language for the referenced entity and add some additional logic that ensures we're not trying to call getTranslation when we shouldn't.

Remaining tasks

Create a patch that resolves the referenced entity to the correct language.

πŸ› Bug report
Status

Active

Version

2.3

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States apmsooner

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @apmsooner
  • πŸ‡ΊπŸ‡ΈUnited States apmsooner
  • Merge request !107Refactor getTranslation() logic. β†’ (Open) created by apmsooner
  • πŸ‡ΊπŸ‡ΈUnited States apmsooner
  • πŸ‡ΊπŸ‡ΈUnited States apmsooner
  • Pipeline finished with Failed
    4 months ago
    Total: 279s
    #414134
  • First commit to issue fork.
  • πŸ‡¦πŸ‡ΊAustralia almunnings Melbourne, πŸ‡¦πŸ‡Ί

    Do you perceive RouteEntityExtra, EntityLoadRevision and EntityConnectionQueryHelper having the same issue with their getTranslated code?

    I'm thinking we abstract the lot into a trait, which allows us to be consistent and possibly feature flag the behaviour

  • πŸ‡¦πŸ‡ΊAustralia almunnings Melbourne, πŸ‡¦πŸ‡Ί
  • πŸ‡ΊπŸ‡ΈUnited States apmsooner

    @almunnings, i'm assuming yes an abstraction may be favorable but also a behavioral setting to how a site wants to handle. I found in the Wunder starter kit that they also have their own patch (https://patch-diff.githubusercontent.com/raw/drupal-graphql/graphql/pull...) that is addressing similar errors but they are just returning NULL which wouldn't be the expected behavior for everyone. I think there perhaps needs to be an underlying global setting that determines if default language fallbacks should be returned everywhere applicable.

  • πŸ‡ΊπŸ‡ΈUnited States apmsooner

    Noting also that the Wunder patch referenced above is against the graphql module so do we address these issues there or within graphql_compose? It certainly feels at least graphql_compose is more actively maintained but leveraging functions from graphql which seem to be the source of the underlying issues we're seeing.

  • Status changed to Needs review 17 days ago
  • πŸ‡¦πŸ‡ΊAustralia almunnings Melbourne, πŸ‡¦πŸ‡Ί

    Bigger commit here.
    Might need to lean on our buddies Wunder and jmolivas to test.

    Anywhere we were loading translations i've shifted it off to a trait that has a hook.

    If you have custom logic beyond whatever I'm doing here, probably the hook is a good way about it?

  • πŸ‡¦πŸ‡ΊAustralia almunnings Melbourne, πŸ‡¦πŸ‡Ί

    Per your testing requirements

    query MyQuery {
      node(id: "f099a6cd-f63b-4f9b-ba26-238cf2271fdc") {
        ... on NodePage {
          tags {
            __typename
            ... on TermTags {
              id
              name
              langcode {
                id
              }
            }
          }
        }
      }
    }
    

    Response

    {
      "data": {
        "node": {
          "tags": [
            {
              "__typename": "TermTags",
              "id": "1",
              "name": "AAAA",
              "langcode": {
                "id": "en"
              }
            },
            {
              "__typename": "TermTags",
              "id": "2",
              "name": "BBBB",
              "langcode": {
                "id": "en"
              }
            },
            {
              "__typename": "TermTags",
              "id": "3",
              "name": "CCCC",
              "langcode": {
                "id": "bn"
              }
            }
          ]
        }
      }
    }
    
Production build 0.71.5 2024