Skip to content

fix: report a provider failure when reading pull request files - #132

Draft
HarshMN2345 wants to merge 2 commits into
mainfrom
fix/pull-request-files-response
Draft

fix: report a provider failure when reading pull request files#132
HarshMN2345 wants to merge 2 commits into
mainfrom
fix/pull-request-files-response

Conversation

@HarshMN2345

Copy link
Copy Markdown
Member

Problem

getPullRequestFiles() assumed every response body was a list of file records:

$files = $response['body'] ?? [];
$allFiles = array_merge($allFiles, $files);

GitHub checked no status at all, so an authorization, rate-limit or gateway response reached array_merge() and raised a TypeError — Appwrite reported an unexpected 500 instead of a controlled failure. Gitea and Forgejo checked the status but not the body, and raised the identical TypeError on a non-JSON body (an HTML error page from a proxy decodes to a string).

Reading an error payload as a file list is the quieter half, and it does not crash:

Adapter Status checked {"message": "Bad credentials"} at 200 HTML error page at 200
GitHub no returned the payload as the file list TypeError
Gitea / Forgejo yes returned the payload as the file list TypeError
GitLab yes returned [{"filename": ""}] returned []
Bitbucket yes [], correctly — its pages are objects returned []

Both consumers read filename / previous_filename off the result to decide which deployments a push affects, so a failed fetch that returns an empty list looks like a pull request that changed nothing, and the deployments are silently skipped. That failure mode reaches no error tracker at all.

Fix

Check the status before the body on GitHub, and require a list of file records everywhere before merging one. Pagination is unchanged in every adapter.

Only GitHub is released today, which is why it is the only one reporting this — not the only one affected.

Test plan

Base now drives these paths from canned responses, since a live forge cannot be made to page or fail on demand. Each adapter describes its own page shape through pullRequestFilesPage(); Gogs opts out through the $supportsPullRequestLookup flag it already sets, and Forgejo inherits Gitea's coverage.

Four tests per adapter — pagination across two pages, 401/403/404/500, a failure on a later page, and malformed bodies. Reverting src/ alone fails 7 of them, across all five supported adapters, including both array_merge() TypeErrors. The pagination tests pass before and after, which is what shows paging is untouched.

composer lint and composer check are clean.

Note for review: these run through setupAdapter(), so they need the usual credentials or compose stack. I could not bring a forge up locally (Docker daemon unresponsive) and verified the harness with throwaway subclasses that stub setupAdapter(). CI is the first run through the real path.

🤖 Generated with Claude Code

getPullRequestFiles() assumed every response body was a list of file
records. GitHub checked no status at all, so an authorization, rate
limit or gateway response reached array_merge() and raised a TypeError;
Gitea and Forgejo checked the status but not the body, and raised the
same TypeError on a non-JSON body. Both surfaced as an unexpected 500
rather than a controlled failure.

Reading an error payload as a file list is the quieter half of this.
GitLab turned one into a single diff with an empty path, and Bitbucket
returned no files at all, so a failed fetch was indistinguishable from
a pull request that changed nothing.

Check the status before the body on GitHub, and require a list of file
records everywhere before merging one. Pagination is unchanged.

Base now drives these paths from canned responses, since a live forge
cannot be made to page or fail on demand. Adapters describe their own
page shape; Gogs opts out through the pull request lookup flag it
already sets.
@greptile-apps

greptile-apps Bot commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR makes pull-request file retrieval fail explicitly on provider errors or malformed response bodies instead of returning misleading empty results or triggering type errors.

  • Adds HTTP-status validation to GitHub pull-request file pagination.
  • Validates provider-specific page shapes across GitHub, GitLab, Gitea/Forgejo, and Bitbucket.
  • Adds shared replay-driven coverage for pagination, provider failures, later-page failures, and malformed bodies.

Confidence Score: 5/5

The PR appears safe to merge because no blocking failure remains.

No blocking failure remains.

Important Files Changed

Filename Overview
src/VCS/Adapter/Git/GitHub.php Adds status and list-shape validation before merging paginated GitHub pull-request files.
src/VCS/Adapter/Git/GitLab.php Rejects malformed merge-request diff bodies while preserving empty-list pagination termination.
src/VCS/Adapter/Git/Gitea.php Requires pull-request file pages to be lists; Forgejo inherits the same validation.
src/VCS/Adapter/Git/Bitbucket.php Converts malformed diffstat page objects and values collections from silent termination into explicit failures.
tests/VCS/Base.php Adds shared mocked-response tests for pagination and provider failure handling across supported adapters.
tests/VCS/Adapter/GitLabTest.php Defines GitLab’s page shape and prepends the merge-request readiness response required by its call sequence.
tests/VCS/Adapter/BitbucketTest.php Defines Bitbucket’s object-based diffstat pagination fixture and applicable malformed-body case.
tests/VCS/Adapter/GitHubTest.php Allows replay mocks to bypass GitHub App token initialization.

Reviews (2): Last reviewed commit: "style: keep the pull request files comme..." | Re-trigger Greptile

@HarshMN2345
HarshMN2345 marked this pull request as draft August 17, 2026 08:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant