diff --git a/CHANGELOG.md b/CHANGELOG.md index 5215b976c..dbc482b97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ - Telegram: stop typing after tool results. Thanks @AbhisekBasu1 for PR #322. - Telegram: include sender identity in group envelope headers. (#336) - Telegram: support forum topics with topic-isolated sessions and message_thread_id routing. Thanks @HazAT, @nachoiacovino, @RandyVentures for PR #321/#333/#334. +- iMessage: ignore disconnect errors during shutdown (avoid unhandled promise rejections). Thanks @antons for PR #359. - Messages: stop defaulting ack reactions to 👀 when identity emoji is missing. - Auto-reply: require slash for control commands to avoid false triggers in normal text. - Auto-reply: flag error payloads and improve Bun socket error messaging. Thanks @emanuelst for PR #331. diff --git a/README.md b/README.md index fb6a29ba2..6c8a295fc 100644 --- a/README.md +++ b/README.md @@ -453,5 +453,5 @@ Thanks to all clawtributors: azade-c andranik-sahakyan adamgall jalehman jarvis-medmatic mneves75 regenrek tobiasbischoff MSch obviyus dbhurley Asleep123 Iamadig imfing kitze nachoiacovino VACInc cash-echo-bot claude kiranjd pcty-nextgen-service-account minghinmatthewlam - ngutman onutc oswalpalash snopoke ManuelHettich loukotal hugobarauna AbhisekBasu1 emanuelst dantelex erikpr1994 + ngutman onutc oswalpalash snopoke ManuelHettich loukotal hugobarauna AbhisekBasu1 emanuelst dantelex erikpr1994 antons

diff --git a/src/imessage/monitor.test.ts b/src/imessage/monitor.test.ts index 773ff55c6..52cae4963 100644 --- a/src/imessage/monitor.test.ts +++ b/src/imessage/monitor.test.ts @@ -412,4 +412,40 @@ describe("monitorIMessageProvider", () => { }), ); }); + + it("does not trigger unhandledRejection when aborting during shutdown", async () => { + requestMock.mockImplementation((method: string) => { + if (method === "watch.subscribe") + return Promise.resolve({ subscription: 1 }); + if (method === "watch.unsubscribe") + return Promise.reject(new Error("imsg rpc closed")); + return Promise.resolve({}); + }); + + const abortController = new AbortController(); + const unhandled: unknown[] = []; + const onUnhandled = (reason: unknown) => { + unhandled.push(reason); + }; + process.on("unhandledRejection", onUnhandled); + + try { + const run = monitorIMessageProvider({ + abortSignal: abortController.signal, + }); + await waitForSubscribe(); + await flush(); + + abortController.abort(); + await flush(); + + closeResolve?.(); + await run; + } finally { + process.off("unhandledRejection", onUnhandled); + } + + expect(unhandled).toHaveLength(0); + expect(stopMock).toHaveBeenCalled(); + }); }); diff --git a/src/imessage/monitor.ts b/src/imessage/monitor.ts index 14884d862..7a191f22d 100644 --- a/src/imessage/monitor.ts +++ b/src/imessage/monitor.ts @@ -452,7 +452,9 @@ export async function monitorIMessageProvider( // Ignore disconnect errors during shutdown. }); } - void client.stop(); + void client.stop().catch(() => { + // Ignore disconnect errors during shutdown. + }); }; abort?.addEventListener("abort", onAbort, { once: true });