Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GraphQL pagination breaks on partial results #6013

Open
laughedelic opened this issue Jul 28, 2022 · 2 comments
Open

GraphQL pagination breaks on partial results #6013

laughedelic opened this issue Jul 28, 2022 · 2 comments
Labels
bug Something isn't working gh-api relating to the gh api command p2 Affects more than a few users but doesn't prevent core functions

Comments

@laughedelic
Copy link

laughedelic commented Jul 28, 2022

Describe the bug

►  gh --version
gh version 2.14.3 (2022-07-26)
https://github.com/cli/cli/releases/tag/v2.14.3

I'm trying to use GraphQL API to fetch repositories with a certain file, including its content. The file is not expected to be present in every repository, I'm only interested in those where it exists. GraphQL API returns partial results (replacing the file field with null) in such cases and a list of errors with the reason. As I understand from this article: https://hasura.io/blog/graphql-nulls-cheatsheet/#nulls-in-the-response it's normal and shouldn't be considered a failed request. So I expect gh to keep querying subsequent pages and accumulate results and errors. Instead, it fetches the first page and stops, as if the query has failed.

Steps to reproduce the behavior

An example query:

gh api graphql \
  --paginate \
  -f query='query ($endCursor: String) {
    organization(login: "...") {
      repositories(
        first: 10
        after: $endCursor
      ) {
        pageInfo {
          endCursor
          hasNextPage
        }
        nodes {
          url
          object(expression: "HEAD") {
            ... on Commit {
              file(path: ".github/dependabot.yml") {
                object {
                  ... on Blob { text }
                }
              }
            }
          }
        }
      }
    }
  }'

Result:

{
  "data": {
    "organization": {
      "repositories": {
        "pageInfo": {
          "endCursor": "Y3Vyc29yOnYyOpK5MjAyMi0wNy0yMF...",
          "hasNextPage": true
        },
        "nodes": [
          {
            "url": "https://github.com/org/repo1",
            "object": {
              "file": {
                "object": {
                  "text": "version: 2\nupdates:\n  - package-ecosystem: \"github-actions\"\n    directory: \"/\"\n    schedule:\n      interval: \"daily\""
                }
              }
            }
          },
          {
            "url": "https://github.com/org/repo2",
            "object": {
              "file": null
            }
          }
        ]
      }
    }
  },
  "errors": [
    {
      "type": "NOT_FOUND",
      "path": [ "organization", "repositories", "nodes", 1, "object", "file" ],
      "locations": [ { "line": 18, "column": 15 } ],
      "message": "Could not resolve file for path '.github/dependabot.yml'."
    }
  ]
}

I redacted results for brevity. Notice "hasNextPage": true.

You can see that the response data contains some results with the file's contents and some results with "file": null. And every null case is explained in the errors array. These errors are not fatal and shouldn't fail the query.

Expected vs actual behavior

  • Expected: get all pages with partial results from each query accumulated in the .data.organization.repositories.nodes array and all errors accumulated in the .errors array.
  • Actual: gh stops after the first page

Relevant links

Potentially related issues

@laughedelic laughedelic added the bug Something isn't working label Jul 28, 2022
@cliAutomation cliAutomation added the needs-triage needs to be reviewed label Jul 28, 2022
@mislav
Copy link
Contributor

mislav commented Aug 10, 2022

Thanks for the detailed report! Absolutely agreed that GraphQL errors are not always fatal and that in this case pagination should continue even if there were some partial GraphQL errors. This is perhaps indicative of gh api possibly being over-zealous with error handling and that we should possibly add an opt out mechanism so that the consumer itself can decide how to handle errors, particularly those from GraphQL. But, as a stopgap fix, we could just disable GraphQL error processing in --paginate mode and return all server results verbatim.

@mislav mislav added p2 Affects more than a few users but doesn't prevent core functions and removed needs-triage needs to be reviewed labels Aug 10, 2022
@laughedelic
Copy link
Author

Thanks for the feedback!

as a stopgap fix, we could just disable GraphQL error processing in --paginate mode and return all server results verbatim.

this sounds good 👍

@andyfeller andyfeller added the gh-api relating to the gh api command label Oct 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working gh-api relating to the gh api command p2 Affects more than a few users but doesn't prevent core functions
Projects
None yet
Development

No branches or pull requests

4 participants