diff --git a/packages/ai/src/chatTransport.test.ts b/packages/ai/src/chatTransport.test.ts index cba7d672a..5a80b3117 100644 --- a/packages/ai/src/chatTransport.test.ts +++ b/packages/ai/src/chatTransport.test.ts @@ -546,6 +546,70 @@ describe("TriggerChatTransport", function () { expect(runStore.get("chat-inactive")).toBeUndefined(); }); + it("reports inactive reconnect cleanup delete failures through onError", async function () { + const errors: TriggerChatTransportError[] = []; + const runStore = new FailingCleanupDeleteRunStore(1); + runStore.set({ + chatId: "chat-inactive-delete-failure", + runId: "run_inactive_delete_failure", + publicAccessToken: "pk_inactive_delete_failure", + streamKey: "chat-stream", + lastEventId: "10-0", + isActive: false, + }); + + const transport = new TriggerChatTransport({ + task: "chat-task", + stream: "chat-stream", + accessToken: "pk_trigger", + runStore, + onError: function onError(error) { + errors.push(error); + }, + }); + + const stream = await transport.reconnectToStream({ + chatId: "chat-inactive-delete-failure", + }); + + expect(stream).toBeNull(); + expect(errors).toHaveLength(1); + expect(errors[0]).toMatchObject({ + phase: "reconnect", + chatId: "chat-inactive-delete-failure", + runId: "run_inactive_delete_failure", + }); + expect(errors[0]?.error.message).toBe("cleanup delete failed"); + }); + + it("returns null when inactive reconnect cleanup delete and onError both fail", async function () { + const runStore = new FailingCleanupDeleteRunStore(1); + runStore.set({ + chatId: "chat-inactive-delete-onerror-failure", + runId: "run_inactive_delete_onerror_failure", + publicAccessToken: "pk_inactive_delete_onerror_failure", + streamKey: "chat-stream", + lastEventId: "10-0", + isActive: false, + }); + + const transport = new TriggerChatTransport({ + task: "chat-task", + stream: "chat-stream", + accessToken: "pk_trigger", + runStore, + onError: async function onError() { + throw new Error("onError failed"); + }, + }); + + const stream = await transport.reconnectToStream({ + chatId: "chat-inactive-delete-onerror-failure", + }); + + expect(stream).toBeNull(); + }); + it("supports custom payload mapping and trigger options resolver", async function () { let receivedTriggerBody: Record | undefined; let receivedResolverChatId: string | undefined; diff --git a/packages/ai/src/chatTransport.ts b/packages/ai/src/chatTransport.ts index 5c6392852..9d5d3465d 100644 --- a/packages/ai/src/chatTransport.ts +++ b/packages/ai/src/chatTransport.ts @@ -258,7 +258,16 @@ export class TriggerChatTransport< } if (!runState.isActive) { - await this.runStore.delete(options.chatId); + try { + await this.runStore.delete(options.chatId); + } catch (error) { + await this.reportError({ + phase: "reconnect", + chatId: runState.chatId, + runId: runState.runId, + error: normalizeError(error), + }); + } return null; }