Skip to content

fix(server-catalog): stay quiet when OAuth authorization is cancelled - #204

Merged
marekdano merged 1 commit into
contextforge-org:mainfrom
ShaoLOWu:fix/catalog-oauth-cancel-quiet
Oct 27, 2026
Merged

marekdano merged 1 commit into
contextforge-org:mainfrom
ShaoLOWu:fix/catalog-oauth-cancel-quiet

Conversation

@ShaoLOWu

Copy link
Copy Markdown
Contributor

Summary

Closing the OAuth popup without completing authorization is a deliberate user action, not a failure, so the Server catalog page and the Add-server dialog no longer report it. Both handleAuthorize and handleOAuthSubmit now return early on OAuthCancelledError instead of notifying, mirroring the MCP Servers page (Servers.tsx), which already discards the cancellation silently.

Fixes IBM/mcp-context-forge#7303 (the catalog UI lives in this repo).

What changed

  • src/pages/ServerCatalog.tsx — both OAuth catch blocks return early on OAuthCancelledError; genuine authorization failures keep surfacing their reason, and the dialog stays open for a retry.
  • src/pages/ServerCatalog.test.tsx — the cancelled-authorization test now rejects with OAuthCancelledError and asserts no cancellation notice appears anywhere (previously it rejected with a plain Error carrying the same untranslated text, covering cancel and failure identically); a new dialog test covers the real-failure path (provider reason still shown), and a new page-level test covers the Authorize menu action staying quiet on cancellation.

What is intentionally not here

Surfacing the provider's denial reason via OAuthAuthorizationError (the remaining suggestion in the issue) lands naturally after #199 adds the class to src/api/servers.ts; this PR does not duplicate it.

How I checked

  • npx vitest run src/pages/ServerCatalog.test.tsx — 78/78 green (includes the three new/updated tests)
  • npx tsc -b tsconfig.app.json — clean (after npx orval generation)
  • npx eslint / npx prettier --check — clean on both changed files

Disclosure

This change was drafted with AI assistance (Claude via WorkBuddy); the diff was reviewed and all verification commands were run by the contributor before submission.

Closing the OAuth popup without completing authorization is a deliberate
user action, not a failure, so ServerCatalog no longer reports it.
Previously both `handleAuthorize` (page-level notice above the grid) and
`handleOAuthSubmit` (notice inside the Add-server dialog) passed the raw
`OAuthCancelledError` message ("OAuth authorization was cancelled",
untranslated) straight into their notification state.

Both catch blocks now return early on `OAuthCancelledError` instead of
notifying, mirroring the MCP Servers page (Servers.tsx), which already
discards the cancellation silently. Genuine authorization failures keep
surfacing their reason, and the dialog stays open for a retry in both
cases.

Tests: the cancelled-authorization test now uses `OAuthCancelledError`
and asserts no cancellation notice appears anywhere (previously it
rejected with a plain `Error` carrying the same text, covering cancel
and failure identically); a new dialog test covers the real-failure path
(provider reason still shown), and a new page-level test covers the
Authorize menu action staying quiet on cancellation.

Fixes IBM/mcp-context-forge#7303 (the catalog UI lives in this repo).

Note: surfacing the provider's denial reason via `OAuthAuthorizationError`
(the remaining suggestion in that issue) lands naturally after contextforge-org#199 adds
the class to `src/api/servers.ts`; this PR intentionally does not
duplicate it.

Verification: `vitest run src/pages/ServerCatalog.test.tsx` 78/78 green;
`tsc -b tsconfig.app.json` clean (after `orval` generation); eslint and
prettier clean on both changed files.

Assisted-by: AI (Claude via WorkBuddy) — diff reviewed and verified by
the human contributor before submission.
Signed-off-by: ShaoLOWu <3034261766@qq.com>
@ShaoLOWu
ShaoLOWu force-pushed the fix/catalog-oauth-cancel-quiet branch from 4c5f479 to 5c343d0 Compare October 23, 2026 10:36
@a-effort
a-effort requested a balanced review from Copilot October 23, 2026 17:40

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The changes are narrowly scoped, preserve cleanup and genuine-error handling, and include focused regression coverage with no unresolved findings.

No open issues 🎉

What changed in this PR

This PR aligns the Server catalog’s OAuth cancellation handling with the MCP Servers page: closing the popup stays silent, while genuine failures remain visible and the Add-server dialog stays open for retry.

Changes:

  • Return early on OAuthCancelledError in both catalog authorization handlers.
  • Add regression coverage for silent cancellation from card actions and the dialog, while preserving failure feedback and retry behavior.
File Description
src/​pages/​ServerCatalog.tsx Suppresses cancellation notifications in both OAuth flows.
src/​pages/​ServerCatalog.test.tsx Covers cancellation, retry, and genuine authorization failure feedback.

Review effort: Balanced

@a-effort a-effort left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! 🚀

non-blocking LLM feedback:

The @/api/servers mock defines its own OAuthCancelledError instead of using the exported one, so the test checks the page against a class the test itself creates. If triggerOAuthAuthorization starts rejecting with a different type, this test still passes. The @/api/oauth mock directly above already spreads the original module, and the same approach works here:

vi.mock("@/api/servers", async (importOriginal) => ({
  ...(await importOriginal<typeof import("@/api/servers")>()),
  serversApi: {
    openOAuthAuthorizationPopup: vi.fn(),
    triggerOAuthAuthorization: vi.fn(),
    toggleEnabled: vi.fn(),
    fetchToolsAfterOAuth: vi.fn(),
  },
}));

@ShaoLOWu

Copy link
Copy Markdown
Contributor Author

Hi, gentle nudge - this has been sitting approved (thanks @a-effort!) with green CI for about ten days now. Is there anything else needed on my side, or is this waiting on a merge window / branch-protection requirements? Happy to help if a rebase or any adjustments would unblock it. Thanks!

@marekdano marekdano left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The fix does what it says, and it matches how Servers.tsx already handles OAuthCancelledError.

  • Both paths covered: handleAuthorize (card action) and the dialog handler both return early on OAuthCancelledError.
  • Cleanup preserved: In the dialog path, authWindow.close() runs before the early return, and the finally blocks still reset oauthAuthorizing/endAdding.
  • Retry works: pendingOAuthGatewayId stays set after a cancel, so a retry reuses the registered gateway instead of registering again.
  • Real failures still surface: The new "Provider denied the request" test covers this.
  • Tests: I ran ServerCatalog.test.tsx on the branch, and all 78 tests pass.

Non-blocking, @ShaoLOWu this can be as follow-up:

Mock uses its own error class. I agree with @a-effort's note. The @/api/servers mock defines its own OAuthCancelledError, so the tests only prove the page works with the mock's class. Spreading importOriginal, as the @/api/oauth mock above it does, would make the tests use the real class. The "Real error classes" comment would then be unnecessary, since the class in the mock isn't the real one.

LGTM 🚀

@marekdano
marekdano merged commit 4a5465b into contextforge-org:main Oct 27, 2026
5 checks passed
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.

[Bug] Server catalog shows an untranslated OAuth failure message

4 participants