From 5ce2f2854be0af1b8e91b620e2ed1d62cb80d544 Mon Sep 17 00:00:00 2001 From: Shaojin Wen Date: Sun, 17 May 2026 08:28:22 +0800 Subject: [PATCH] fix(test): clear boundedPromise timers to prevent unhandled rejections (#4220) boundedPromise timeouts could fire after test completion, causing vitest to exit with code 1 due to unhandled rejection. Add clear() method and cleanup all pending timers in the finally block. --- .../sdk-typescript/abort-and-lifecycle.test.ts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/integration-tests/sdk-typescript/abort-and-lifecycle.test.ts b/integration-tests/sdk-typescript/abort-and-lifecycle.test.ts index 922dc1f9e9..25f823534f 100644 --- a/integration-tests/sdk-typescript/abort-and-lifecycle.test.ts +++ b/integration-tests/sdk-typescript/abort-and-lifecycle.test.ts @@ -328,6 +328,7 @@ describe('AbortController and Process Lifecycle (E2E)', () => { const promise = new Promise((resolve, reject) => { resolveFn = () => { if (timer !== undefined) clearTimeout(timer); + timer = undefined; resolve(); }; pendingReject = reject; @@ -335,10 +336,17 @@ describe('AbortController and Process Lifecycle (E2E)', () => { const startTimer = () => { if (timer !== undefined) return; timer = setTimeout(() => { + timer = undefined; pendingReject(new Error(`${label} timeout after ${ms}ms`)); }, ms); }; - return { promise, resolve: () => resolveFn(), startTimer }; + const clear = () => { + if (timer !== undefined) { + clearTimeout(timer); + timer = undefined; + } + }; + return { promise, resolve: () => resolveFn(), startTimer, clear }; }; const canUseToolCalled = boundedPromise( @@ -348,6 +356,12 @@ describe('AbortController and Process Lifecycle (E2E)', () => { const inputStreamDone = boundedPromise('inputStreamDone', 15000); const firstResult = boundedPromise('firstResult', 30000); const secondResult = boundedPromise('secondResult', 30000); + const pendingTimers = [ + canUseToolCalled, + inputStreamDone, + firstResult, + secondResult, + ]; // firstResult begins as soon as the query starts. firstResult.startTimer(); @@ -454,6 +468,7 @@ describe('AbortController and Process Lifecycle (E2E)', () => { const content = await helper.readFile('test.txt'); expect(content).toBe('original content'); } finally { + for (const t of pendingTimers) t.clear(); await q.close(); } });