Skip to content

Commit 4006a68

Browse files
Handle inactive reconnect cleanup delete failures non-fatally
Co-authored-by: Eric Allam <eric@trigger.dev>
1 parent 677fc06 commit 4006a68

File tree

2 files changed

+74
-1
lines changed

2 files changed

+74
-1
lines changed

packages/ai/src/chatTransport.test.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -546,6 +546,70 @@ describe("TriggerChatTransport", function () {
546546
expect(runStore.get("chat-inactive")).toBeUndefined();
547547
});
548548

549+
it("reports inactive reconnect cleanup delete failures through onError", async function () {
550+
const errors: TriggerChatTransportError[] = [];
551+
const runStore = new FailingCleanupDeleteRunStore(1);
552+
runStore.set({
553+
chatId: "chat-inactive-delete-failure",
554+
runId: "run_inactive_delete_failure",
555+
publicAccessToken: "pk_inactive_delete_failure",
556+
streamKey: "chat-stream",
557+
lastEventId: "10-0",
558+
isActive: false,
559+
});
560+
561+
const transport = new TriggerChatTransport({
562+
task: "chat-task",
563+
stream: "chat-stream",
564+
accessToken: "pk_trigger",
565+
runStore,
566+
onError: function onError(error) {
567+
errors.push(error);
568+
},
569+
});
570+
571+
const stream = await transport.reconnectToStream({
572+
chatId: "chat-inactive-delete-failure",
573+
});
574+
575+
expect(stream).toBeNull();
576+
expect(errors).toHaveLength(1);
577+
expect(errors[0]).toMatchObject({
578+
phase: "reconnect",
579+
chatId: "chat-inactive-delete-failure",
580+
runId: "run_inactive_delete_failure",
581+
});
582+
expect(errors[0]?.error.message).toBe("cleanup delete failed");
583+
});
584+
585+
it("returns null when inactive reconnect cleanup delete and onError both fail", async function () {
586+
const runStore = new FailingCleanupDeleteRunStore(1);
587+
runStore.set({
588+
chatId: "chat-inactive-delete-onerror-failure",
589+
runId: "run_inactive_delete_onerror_failure",
590+
publicAccessToken: "pk_inactive_delete_onerror_failure",
591+
streamKey: "chat-stream",
592+
lastEventId: "10-0",
593+
isActive: false,
594+
});
595+
596+
const transport = new TriggerChatTransport({
597+
task: "chat-task",
598+
stream: "chat-stream",
599+
accessToken: "pk_trigger",
600+
runStore,
601+
onError: async function onError() {
602+
throw new Error("onError failed");
603+
},
604+
});
605+
606+
const stream = await transport.reconnectToStream({
607+
chatId: "chat-inactive-delete-onerror-failure",
608+
});
609+
610+
expect(stream).toBeNull();
611+
});
612+
549613
it("supports custom payload mapping and trigger options resolver", async function () {
550614
let receivedTriggerBody: Record<string, unknown> | undefined;
551615
let receivedResolverChatId: string | undefined;

packages/ai/src/chatTransport.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,16 @@ export class TriggerChatTransport<
258258
}
259259

260260
if (!runState.isActive) {
261-
await this.runStore.delete(options.chatId);
261+
try {
262+
await this.runStore.delete(options.chatId);
263+
} catch (error) {
264+
await this.reportError({
265+
phase: "reconnect",
266+
chatId: runState.chatId,
267+
runId: runState.runId,
268+
error: normalizeError(error),
269+
});
270+
}
262271
return null;
263272
}
264273

0 commit comments

Comments
 (0)