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.