Querying for translations of a node with one or more unpublished translations causes fatal error

Created on 30 July 2024, 5 months ago
Updated 15 September 2024, 3 months ago

Problem/Motivation

In recent versions of the module a new field has been added to retrieve translations of a node. All works in the cases:

1. the node has no translations
2. the node has one or more publishded translations

however, if the node has one translation that is unpublished, and the user doing the query cannot access unpublished nodes, the query fails with this fatal error:

{
    "$operation": {
        "queryId": null,
        "query": "query GetNodeByPath($path: String!, $langcode: String!) {\n  route(path: $path, langcode: $langcode) {\n    __typename\n    ... on RouteInternal {\n      __typename\n      entity {\n        ...FragmentNodeUnion\n      }\n    }\n    ... on RouteRedirect {\n      __typename\n      status\n      url\n      internal\n    }\n  }\n}\n\nfragment FragmentMetaTag on MetaTagValue {\n  __typename\n  tag\n  attributes {\n    name\n    content\n  }\n}\n\nfragment FragmentTextSummary on TextSummary {\n  value\n  processed\n  format\n  summary\n}\n\nfragment FragmentImage on Image {\n  url\n  width\n  height\n  alt\n  title\n  size\n  mime\n}\n\nfragment FragmentUser on User {\n  name\n  mail\n}\n\nfragment FragmentNodeTranslation on Translation {\n  __typename\n  path\n  langcode {\n    id\n  }\n}\n\nfragment FragmentNodeArticle on NodeArticle {\n  excerpt\n  sticky\n  body {\n    ...FragmentTextSummary\n  }\n  image {\n    ...FragmentImage\n  }\n  author {\n    __typename\n    ... on User {\n      ...FragmentUser\n    }\n  }\n  translations {\n    ...FragmentNodeTranslation\n  }\n}\n\nfragment FragmentText on Text {\n  value\n  processed\n  format\n}\n\nfragment FragmentParagraphFormattedText on ParagraphFormattedText {\n  formattedTextHeading: heading\n  formattedTextText: formattedText {\n    ...FragmentText\n  }\n}\n\nfragment FragmentLink on Link {\n  __typename\n  title\n  url\n  internal\n}\n\nfragment FragmentParagraphLink on ParagraphLink {\n  links {\n    ...FragmentLink\n  }\n}\n\nfragment FragmentFile on File {\n  name\n  url\n  size\n  mime\n  description\n}\n\nfragment FragmentMediaAudio on MediaAudio {\n  name\n  mediaAudioFile {\n    ...FragmentFile\n  }\n}\n\nfragment FragmentMediaDocument on MediaDocument {\n  name\n  mediaDocumentFile: mediaDocument {\n    ...FragmentFile\n  }\n}\n\nfragment FragmentMediaImage on MediaImage {\n  name\n  mediaImage {\n    ...FragmentImage\n  }\n}\n\nfragment FragmentMediaRemoteVideo on MediaRemoteVideo {\n  name\n  mediaOembedVideo\n}\n\nfragment FragmentMediaVideo on MediaVideo {\n  name\n  mediaVideoFile {\n    ...FragmentFile\n  }\n}\n\nfragment FragmentMediaUnion on MediaInterface {\n  __typename\n  id\n  ...FragmentMediaAudio\n  ...FragmentMediaDocument\n  ...FragmentMediaImage\n  ...FragmentMediaRemoteVideo\n  ...FragmentMediaVideo\n}\n\nfragment FragmentParagraphImage on ParagraphImage {\n  image {\n    ...FragmentMediaUnion\n  }\n}\n\nfragment FragmentParagraphVideo on ParagraphVideo {\n  video {\n    ...FragmentMediaUnion\n  }\n}\n\nfragment FragmentParagraphFileAttachments on ParagraphFileAttachment {\n  fileAttachmentsParagraphHeading: heading\n  fileAttachmentsParagraphFormattedText: formattedText {\n    ...FragmentText\n  }\n  fileAttachments {\n    ...FragmentMediaUnion\n  }\n}\n\nfragment FragmentParagraphHero on ParagraphHero {\n  formattedText {\n    ...FragmentText\n  }\n  image {\n    ...FragmentMediaUnion\n  }\n  primaryLink {\n    ...FragmentLink\n  }\n  secondaryLink {\n    ...FragmentLink\n  }\n  paragraphHeroHeading: heading\n}\n\nfragment FragmentParagraphAccordionItem on ParagraphAccordionItem {\n  __typename\n  id\n  accordionItemHeading: heading\n  accordionItemFormattedText: formattedText {\n    ...FragmentText\n  }\n  contentElements {\n    ... on ParagraphInterface {\n      __typename\n      id\n      ... on ParagraphAccordionItemContentElementsUnion {\n        ...FragmentParagraphFormattedText\n        ...FragmentParagraphImage\n        ...FragmentParagraphLink\n        ...FragmentParagraphFileAttachments\n        ...FragmentParagraphVideo\n      }\n    }\n  }\n}\n\nfragment FragmentParagraphAccordion on ParagraphAccordion {\n  heading\n  accordionLayout\n  primaryLink {\n    ...FragmentLink\n  }\n  accordionFormattedText: formattedText {\n    ...FragmentText\n  }\n  accordionItems {\n    ... on ParagraphInterface {\n      __typename\n      id\n      ...FragmentParagraphAccordionItem\n    }\n  }\n}\n\nfragment FragmentParagraphListingArticle on ParagraphListingArticle {\n  __typename\n  id\n  paragraphListingArticleHeading: heading\n  limit\n}\n\nfragment FragmentArticleTeaser on NodeArticle {\n  __typename\n  id\n  image {\n    ...FragmentImage\n  }\n  path\n  title\n  sticky\n  excerpt\n  created {\n    timestamp\n  }\n  author {\n    __typename\n    ... on User {\n      ...FragmentUser\n    }\n  }\n}\n\nfragment FragmentParagraphLiftupArticle on ParagraphLiftupsArticle {\n  heading\n  articles {\n    ... on NodeArticle {\n      ...FragmentArticleTeaser\n    }\n  }\n}\n\nfragment FragmentNodeFrontpage on NodeFrontpage {\n  contentElements {\n    ... on ParagraphInterface {\n      __typename\n      id\n      ... on NodeFrontpageContentElementsUnion {\n        ...FragmentParagraphFormattedText\n        ...FragmentParagraphLink\n        ...FragmentParagraphImage\n        ...FragmentParagraphVideo\n        ...FragmentParagraphFileAttachments\n        ...FragmentParagraphHero\n        ...FragmentParagraphAccordion\n        ...FragmentParagraphListingArticle\n        ...FragmentParagraphLiftupArticle\n      }\n    }\n  }\n  translations {\n    ...FragmentNodeTranslation\n  }\n}\n\nfragment FragmentNodePage on NodePage {\n  contentElements {\n    ... on ParagraphInterface {\n      __typename\n      id\n      ... on NodePageContentElementsUnion {\n        ...FragmentParagraphFormattedText\n        ...FragmentParagraphLink\n        ...FragmentParagraphImage\n        ...FragmentParagraphVideo\n        ...FragmentParagraphFileAttachments\n        ...FragmentParagraphHero\n        ...FragmentParagraphAccordion\n        ...FragmentParagraphListingArticle\n        ...FragmentParagraphAccordion\n        ...FragmentParagraphLiftupArticle\n      }\n    }\n  }\n  translations {\n    ...FragmentNodeTranslation\n  }\n}\n\nfragment FragmentNodeUnion on NodeInterface {\n  __typename\n  id\n  title\n  status\n  path\n  langcode {\n    id\n  }\n  created {\n    timestamp\n  }\n  changed {\n    timestamp\n  }\n  metatag {\n    ...FragmentMetaTag\n  }\n  ...FragmentNodeArticle\n  ...FragmentNodeFrontpage\n  ...FragmentNodePage\n}",
        "operation": "GetNodeByPath",
        "variables": {
            "path": "\/articles\/article-finnish",
            "langcode": "fi"
        },
        "extensions": null
    },
    "$result->data": {
        "route": {
            "__typename": "RouteInternal",
            "entity": null
        }
    },
    "$result->errors": [
        {
            "message": "Cannot return null for non-nullable field \"NodeArticle.translations\".",
            "locations": [
                {
                    "line": 73,
                    "column": 3
                }
            ],
            "path": [
                "route",
                "entity",
                "translations",
                0
            ]
        }
    ],
    "$result->extensions": []
}

Steps to reproduce

1. Create a node
2. add a translation
3. unpublish the translation
4. query for translations of that node
5. observe the error

Proposed resolution

When retrieving the list of translations, we should handle the case where the user does not have access to the translation like we do when the translation does not actually exist.

🐛 Bug report
Status

Fixed

Version

2.2

Component

Code

Created by

🇫🇮Finland vermario

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

Merge Requests

Comments & Activities

Production build 0.71.5 2024