Repository navigation
fix(server-catalog): stay quiet when OAuth authorization is cancelled - #204
Conversation
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>
4c5f479 to
5c343d0
Compare
There was a problem hiding this comment.
🟢 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
OAuthCancelledErrorin 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
left a comment
There was a problem hiding this comment.
LGTM! 🚀
non-blocking LLM feedback:
The
@/api/serversmock defines its ownOAuthCancelledErrorinstead of using the exported one, so the test checks the page against a class the test itself creates. IftriggerOAuthAuthorizationstarts rejecting with a different type, this test still passes. The@/api/oauthmock 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(),
},
}));
|
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
left a comment
There was a problem hiding this comment.
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 onOAuthCancelledError. - Cleanup preserved: In the dialog path,
authWindow.close()runs before the early return, and thefinallyblocks still resetoauthAuthorizing/endAdding. - Retry works:
pendingOAuthGatewayIdstays 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.tsxon 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 🚀
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
handleAuthorizeandhandleOAuthSubmitnow return early onOAuthCancelledErrorinstead 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 onOAuthCancelledError; 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 withOAuthCancelledErrorand asserts no cancellation notice appears anywhere (previously it rejected with a plainErrorcarrying 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 tosrc/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 (afternpx orvalgeneration)npx eslint/npx prettier --check— clean on both changed filesDisclosure
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.