Repository navigation
fix(frontend): show why a repository never appeared, not an empty dropdown - #5
Open
pranav8764 wants to merge 1 commit into
Open
pranav8764 wants to merge 1 commit into
pranav8764 wants to merge 1 commit into
Conversation
…pdown
A repository connected through the GitHub App never showed up and the UI
gave no reason. The backend was returning 500 (an installation created
under a previous GitHub App can no longer mint a token), but every failure
was swallowed:
- the repository-list catch called setRepositories([]), so a 500 rendered
as an empty, enabled dropdown showing only "-- Select Repository --",
indistinguishable from "this installation genuinely has no repos";
- the installations catch returned { installations: [] }, routing the UI
into the "no installations" branch and rendering an "Install App" button
that told the user to do the thing they had just done;
- nothing read the ?github=connected marker the gateway redirects back
with, so a completed install only showed up on a later full reload.
fetchAPI now throws an ApiError carrying the HTTP status and the gateway's
machine-readable code. It still extends Error, so the ~17 callers that only
read .message are unaffected. Both swallows are replaced with a visible
alert plus Retry, matching the treatment ConnectedRepositories already
used. A failed installations call can no longer render "Install App", and
a failed config call no longer reads as "backend not configured".
Repository connections with status 'revoked' render as "Reconnect
required" with a reconnect action and are kept out of the picker; a
missing or unrecognised status still reads as connected, so this degrades
gracefully until the server-side status lands. 409 INSTALLATION_REVOKED
gets plain-language copy, and any other non-2xx still produces a specific
error rather than an empty dropdown.
Also fixed while here: a refresh silently cleared a pending repository
choice while leaving the project name filled, so "Create & Connect
Project" would create a project with no repository and no warning; the
choice is now preserved unless GitHub stopped offering that repository.
Concurrent fetches are sequence-guarded so an older snapshot cannot land
last and win.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A repository connected through the
archiatros-sreGitHub App never appeared, and the user got no indication why.The backend was returning HTTP 500 — installation
142620052was created under a previous GitHub App and can no longer mint a token:The UI swallowed all of it:
listGitHubRepositories500ssetRepositories([])→ an empty, enabled dropdown showing only-- Select Repository --, indistinguishable from "this installation genuinely has no repos"listGitHubInstallationsfails.catch(… return { installations: [] })→ the "no installations" branch → an "Install App" button telling the user to do the thing they had just done?github=connected, but nothing read the param and there was no polling — the repo only appeared on a later full reloadChange
lib/api.ts—fetchAPInow throws anApiErrorcarrying the HTTPstatusand the gateway's machine-readablecode. It still extendsError, so the ~17 callers that only read.messageare untouched; the signature is unchanged. The gateway's envelope is{"error": CODE, "message": …}, socode ?? erroris read (verified over the wire). AddsdescribeRequestError,settle,isInstallationUsable, andrepositoryConnectionHealth.dashboard/[workspaceId]/page.tsxrepoError/installationsErrorstate; both silent swallows replaced with a visiblerole="alert"+ Retry, matching the treatmentConnectedRepositoriesalready used.?github=connectedviauseSearchParams, refetches once, shows a confirmation, then clears the marker. Wrapped in<Suspense>— without itnext buildfails the route.status === 'revoked'renders as "Reconnect required" with a reconnect action and is excluded from the picker. Missing/unrecognised status still reads as connected, so this degrades gracefully until the server-side status lands.INSTALLATION_REVOKEDgets plain-language copy; any other non-2xx still yields a specific error (e.g.failed to list repositories (HTTP 500 LIST_REPOS_FAILED)) rather than an empty dropdown.dashboard/page.tsx— revoked connections show "Reconnect required" + a Reconnect link instead of a stale "Indexed" badge; leftover raw zinc/red colors migrated to theme tokens.Bugs found and fixed during review
handleCreatethen skipped the attach with no error, producing a project labelled "No Repository". The choice is now preserved unless GitHub stopped offering that repository.nullJSON error body threwTypeErrorinstead ofApiError, defeating everyisApiErrorbranch.Verification
npm test— 26 pass (16 new). The 500 case renders the real page component and asserts the error, the Retry, and the absence of-- Select Repository --.npm run lintclean on changed files;npx tsc --noEmitclean;npm run buildsucceeds.make health8/8, the 500 reproduced in the integration-service log, and the error envelope shape confirmed over the wire.Not yet observable in production
Three behaviours depend on sibling units and are inert until those land — by design, and the code degrades gracefully meanwhile:
repository_connections.statusis stillCHECK (status IN ('connected','disabled','archived','error'))—'revoked'needs the migration.github_installations.statusyet (noinstallation.deletedwebhook handler).INSTALLATION_REVOKEDyet.Blocker (outside this repo, needs the user)
The GitHub App
archiatros-srehas a Setup URL ofhttp://localhost:8080/...but the gateway publishes on 8180. Every row ingithub_install_sessionsstill hasconsumed_at IS NULL, so no install has ever completed. Until that is corrected at https://github.com/settings/apps/archiatros-sre, a fresh install cannot be exercised.🤖 Generated with Claude Code