












@@ -0,0 +1,65 @@
1+import { describe, expect, it, vi } from "vitest";
2+import { chatHandlers } from "./chat.js";
3+import type { GatewayRequestContext } from "./types.js";
4+5+function createMockContext() {
6+const broadcast = vi.fn();
7+const nodeSendToSession = vi.fn();
8+const chatAbortControllers = new Map();
9+const agentRunSeq = new Map<string, number>();
10+const dedupe = new Map();
11+12+return {
13+ broadcast,
14+ nodeSendToSession,
15+ chatAbortControllers,
16+ agentRunSeq,
17+ dedupe,
18+logGateway: { warn: vi.fn(), debug: vi.fn(), error: vi.fn() },
19+addChatRun: vi.fn(),
20+removeChatRun: vi.fn(),
21+};
22+}
23+24+describe("chat.send error broadcast", () => {
25+it("should broadcast error when addChatRun throws", async () => {
26+const ctx = createMockContext();
27+const respond = vi.fn();
28+29+// Make addChatRun throw synchronously (inside the try block at line 2470)
30+ctx.addChatRun.mockImplementation(() => {
31+throw Object.assign(new Error("LLM timeout"), { code: "TIMEOUT" });
32+});
33+34+await chatHandlers["chat.send"]({
35+params: {
36+sessionKey: "main",
37+message: "hello",
38+idempotencyKey: "test-run-1",
39+},
40+respond: respond as never,
41+context: ctx as unknown as GatewayRequestContext,
42+req: {} as never,
43+client: null as never,
44+isWebchatConnect: () => false,
45+});
46+47+// Verify respond was called with error
48+expect(respond).toHaveBeenCalledWith(
49+false,
50+expect.objectContaining({ runId: "test-run-1", status: "error" }),
51+expect.any(Object),
52+expect.any(Object),
53+);
54+55+// Verify broadcastChatError was called (via context.broadcast)
56+expect(ctx.broadcast).toHaveBeenCalledWith(
57+"chat",
58+expect.objectContaining({
59+runId: "test-run-1",
60+state: "error",
61+errorMessage: expect.stringContaining("LLM timeout"),
62+}),
63+);
64+});
65+});
此內容由慣性聚合(RSS閱讀器)自動聚合整理,僅供閱讀參考。 原文來自 — 版權歸原作者所有。