From c60563b7d647303ce15b34690836f3ffd8a7f127 Mon Sep 17 00:00:00 2001 From: cliffhall Date: Mon, 10 Aug 2026 18:09:52 -0400 Subject: [PATCH] fix: observe the derived promise so an unexpected rejection can't go unhandled MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Review feedback (round 2). Narrowing the handler in the previous commit fixed the silent-pass but reintroduced #1947's own failure class on the unexpected path: `then` returns a *derived* promise, and the re-throw rejects that one rather than `call`. The caller doesn't await it until after `disconnect()`, so a rejection arriving while the test is still waiting on progress notifications sits unobserved for seconds and Node reports it as an unhandled rejection. Attach an observer to the derived promise the moment it exists. Nothing is swallowed — it stays rejected, so the caller's `await` still fails the test. Verified both directions with a probe rejecting with a non-ConnectionClosed error and awaiting after a 1.5s gap: without the observer the run reports "Unhandled Rejection" + "Errors 1 error"; with it, the test fails and the run stays clean. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01HDdo1rNRVQnVRRdsqSrvG3 --- .../src/test/integration/mcp/inspectorClient.test.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/clients/web/src/test/integration/mcp/inspectorClient.test.ts b/clients/web/src/test/integration/mcp/inspectorClient.test.ts index 9f5379a7..9a3a690c 100644 --- a/clients/web/src/test/integration/mcp/inspectorClient.test.ts +++ b/clients/web/src/test/integration/mcp/inspectorClient.test.ts @@ -117,7 +117,7 @@ async function getTool(client: InspectorClient, name: string): Promise { * notifications it managed to emit first. */ function settleInFlight(call: Promise): Promise { - return call.then( + const settled = call.then( () => undefined, (error: unknown) => { if ( @@ -129,6 +129,15 @@ function settleInFlight(call: Promise): Promise { throw error; }, ); + // `then` returns a *derived* promise, and the re-throw above rejects that one + // — not `call`. The caller does not await it until after `disconnect()`, so an + // unexpected rejection arriving while the test is still waiting on progress + // notifications would sit unobserved for seconds and be reported as an + // unhandled rejection: precisely the failure this helper exists to prevent. + // Observe it the moment it exists. This does not swallow anything — `settled` + // stays rejected, so the caller's `await` still fails the test. + settled.catch(() => undefined); + return settled; } /** Get all resources from the client via listResources() (paginates if needed). */