diff --git a/src/auto-reply/reply/dispatch-from-config.acp-abort.test.ts b/src/auto-reply/reply/dispatch-from-config.acp-abort.test.ts index a674b40da10..df33e113280 100644 --- a/src/auto-reply/reply/dispatch-from-config.acp-abort.test.ts +++ b/src/auto-reply/reply/dispatch-from-config.acp-abort.test.ts @@ -53,6 +53,26 @@ function setNoAbort() { mocks.tryFastAbortFromMessage.mockResolvedValue(noAbortResult); } +async function raceWithTimeoutResult( + promise: Promise, + timeoutMs: number, + timeoutResult: T, +): Promise { + let timer: ReturnType | undefined; + try { + return await Promise.race([ + promise, + new Promise((resolve) => { + timer = setTimeout(() => resolve(timeoutResult), timeoutMs); + }), + ]); + } finally { + if (timer) { + clearTimeout(timer); + } + } +} + function createMockAcpSessionManager() { return { resolveSession: (params: { cfg: OpenClawConfig; sessionKey: string }) => { @@ -260,12 +280,11 @@ describe("dispatchReplyFromConfig ACP abort", () => { expect(runtime.runTurn).toHaveBeenCalledTimes(1); }); abortController.abort(); - const outcome = await Promise.race([ + const outcome = await raceWithTimeoutResult( dispatchPromise.then(() => "settled" as const), - new Promise<"pending">((resolve) => { - setTimeout(() => resolve("pending"), 100); - }), - ]); + 100, + "pending" as const, + ); releaseTurn?.(); await dispatchPromise;