diff --git a/src/gateway/server-methods/chat.error-broadcast.test.ts b/src/gateway/server-methods/chat.error-broadcast.test.ts new file mode 100644 index 00000000000..dba4ba3b4d7 --- /dev/null +++ b/src/gateway/server-methods/chat.error-broadcast.test.ts @@ -0,0 +1,65 @@ +import { describe, expect, it, vi } from "vitest"; +import { chatHandlers } from "./chat.js"; +import type { GatewayRequestContext } from "./types.js"; + +function createMockContext() { + const broadcast = vi.fn(); + const nodeSendToSession = vi.fn(); + const chatAbortControllers = new Map(); + const agentRunSeq = new Map(); + const dedupe = new Map(); + + return { + broadcast, + nodeSendToSession, + chatAbortControllers, + agentRunSeq, + dedupe, + logGateway: { warn: vi.fn(), debug: vi.fn(), error: vi.fn() }, + addChatRun: vi.fn(), + removeChatRun: vi.fn(), + }; +} + +describe("chat.send error broadcast", () => { + it("should broadcast error when addChatRun throws", async () => { + const ctx = createMockContext(); + const respond = vi.fn(); + + // Make addChatRun throw synchronously (inside the try block at line 2470) + ctx.addChatRun.mockImplementation(() => { + throw Object.assign(new Error("LLM timeout"), { code: "TIMEOUT" }); + }); + + await chatHandlers["chat.send"]({ + params: { + sessionKey: "main", + message: "hello", + idempotencyKey: "test-run-1", + }, + respond: respond as never, + context: ctx as unknown as GatewayRequestContext, + req: {} as never, + client: null as never, + isWebchatConnect: () => false, + }); + + // Verify respond was called with error + expect(respond).toHaveBeenCalledWith( + false, + expect.objectContaining({ runId: "test-run-1", status: "error" }), + expect.any(Object), + expect.any(Object), + ); + + // Verify broadcastChatError was called (via context.broadcast) + expect(ctx.broadcast).toHaveBeenCalledWith( + "chat", + expect.objectContaining({ + runId: "test-run-1", + state: "error", + errorMessage: expect.stringContaining("LLM timeout"), + }), + ); + }); +}); diff --git a/src/gateway/server-methods/chat.ts b/src/gateway/server-methods/chat.ts index 7c8d9392754..7b74147e865 100644 --- a/src/gateway/server-methods/chat.ts +++ b/src/gateway/server-methods/chat.ts @@ -3178,6 +3178,12 @@ export const chatHandlers: GatewayRequestHandlers = { runId: clientRunId, error: formatForLog(err), }); + broadcastChatError({ + context, + runId: clientRunId, + sessionKey, + errorMessage: String(err), + }); } }, "chat.inject": async ({ params, respond, context }) => {