Skip to content

Tell an admin when a query failed instead of showing nothing - #45

Merged
JoeKarow merged 1 commit into
feat/admin-dashboardfrom
feat/admin-error-states
Sep 8, 2026
Merged

Tell an admin when a query failed instead of showing nothing#45
JoeKarow merged 1 commit into
feat/admin-dashboardfrom
feat/admin-error-states

Conversation

@JoeKarow

@JoeKarow JoeKarow commented Sep 8, 2026

Copy link
Copy Markdown
Member

Stacked on #43 — base is feat/admin-dashboard, so merge that one first.

Picks up the loose end from the CodeRabbit review on #43, and finishes what 4a3dcb3 started there.

The problem

4a3dcb3 fixed the 403 case: a revoked admin was seeing an empty dashboard instead of being told. Every other failure was still flattened to null in util/api.ts, with the same consequence — react-query settles a null as success-with-no-data, so a 500 or a dropped connection rendered "No submissions yet" or "Not found".

That is a lie about other people's data, and the sort an admin acts on. "There were no maintainer signups in 2026" is a conclusion someone might reasonably draw and then repeat.

The change

The admin fetchers sort outcomes into three instead of two:

Status Result Why
403 throws AdminAccessError unchanged — useAdminAccess refetches the session so AdminGate can say access was revoked
404 returns null genuinely an answer, not a failure. The pages keep their own "no member matches that address" copy
anything else throws the server or the network broke; isError goes true and the page says so

AdminError is the shared screen, built on the existing ErrorAlert that Forms.tsx already uses for a failed submit — no new error styling.

Two deliberate details:

  • It has a Try again button. Admin queries set retry: false (a 403 is a settled answer, and retrying meant three more with a GitHub resync behind each). So a transient 500 has nothing to recover it unless the person asks.
  • It says outright that access is not the problem. The dashboard's only other failure state is a revoked admin, and an unqualified error would read as that.

Each page checks isError ahead of isPending and its own empty state, and stays behind the revoked check so a 403 still routes to AdminGate rather than rendering both.

Verification

pnpm typecheck and pnpm build pass; prettier clean. Not exercised in a browser — reproducing it wants a forced 5xx from the admin routes, and there are no tests over these pages.

The other half of 4a3dcb3. That commit fixed the 403 case -- a revoked
admin was seeing an empty dashboard rather than being told -- but left
every other failure flattened to null by util/api.ts, with the same
consequence: react-query settles a null as success-with-no-data, so a 500
or a dropped connection rendered "No submissions yet" or "Not found". That
is a lie about other people's data, and the sort of lie an admin acts on.

The admin fetchers now sort the outcomes into three. 403 still throws
AdminAccessError. 404 still returns null, because that one really is an
answer -- no member matches that address -- and the pages keep their own
copy for it. Everything else throws, so isError is true and the pages can
say so.

AdminError is the shared screen, built on the existing ErrorAlert that
Forms.tsx already uses for a failed submit. It carries a Try again button:
admin queries set retry: false, since a 403 is a settled answer and
retrying meant three more of them with a GitHub resync behind each, so a
transient 500 has nothing to recover it unless the person asks. It also
says outright that access is not the problem, because the dashboard's only
other failure state is a revoked admin and an unqualified error would read
as that.

Each page checks isError ahead of isPending and its own empty state, and
stays behind the revoked check so a 403 still routes to AdminGate rather
than showing both.
@coderabbitai

coderabbitai Bot commented Sep 8, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 51ddd375-be32-4ee0-aafe-a0061692a7c7

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@JoeKarow
JoeKarow merged commit 352b4d4 into feat/admin-dashboard Sep 8, 2026
1 check passed
@JoeKarow
JoeKarow deleted the feat/admin-error-states branch September 8, 2026 18:45
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