test(gateway): cover chat.send lifecycle error link

This commit is contained in:
Mason Huang
2026-04-24 21:55:54 +08:00
parent df2325c19b
commit ab4cf98d7f
2 changed files with 43 additions and 0 deletions

View File

@@ -350,6 +350,11 @@ Docs: https://docs.openclaw.ai
- Channels/thread routing: keep outbound replies in existing Slack, Mattermost, Matrix, Telegram, Discord, and QA-channel thread sessions by sharing the Plugin SDK thread-aware route builder across bundled plugins.
- Agents/replay: normalize restored assistant text content before provider replay and prompt submission, so legacy or repaired sessions no longer crash on `assistantMsg.content.flatMap`. (#69850) Thanks @fuller-stack-dev.
### Fixes
- Gateway/chat: register chat.send runs in the chat run registry so lifecycle error events reach the client instead of being silently dropped, fixing stuck 'waiting' state and /abort reporting no active run. (#69747) Thanks @wangshu94.
- fix(gateway): surface chat.send lifecycle errors to clients (#69747). Thanks @wangshu94
## 2026.4.20
### Changes

View File

@@ -1326,6 +1326,44 @@ describe("agent event handler", () => {
expect(agentRunSeq.has("run-chat-send")).toBe(false);
});
it("emits lifecycle chat errors for active chat.send runs with a chat run link", () => {
vi.useFakeTimers();
const { broadcast, chatRunState, clearAgentRunContext, agentRunSeq, handler } = createHarness({
resolveSessionKeyForRun: () => "session-chat-send",
lifecycleErrorRetryGraceMs: 100,
isChatSendRunActive: (runId) => runId === "run-chat-send",
});
chatRunState.registry.add("run-chat-send", {
sessionKey: "session-chat-send",
clientRunId: "run-chat-send",
});
registerAgentRunContext("run-chat-send", { sessionKey: "session-chat-send" });
handler({
runId: "run-chat-send",
seq: 1,
stream: "lifecycle",
ts: Date.now(),
data: { phase: "error", error: "chat.send failed" },
});
vi.advanceTimersByTime(100);
const chatErrors = chatBroadcastCalls(broadcast).filter(
([, payload]) => (payload as { state?: string }).state === "error",
);
expect(chatErrors).toHaveLength(1);
expect(chatErrors[0]?.[1]).toMatchObject({
runId: "run-chat-send",
sessionKey: "session-chat-send",
state: "error",
errorMessage: "chat.send failed",
});
expect(chatRunState.registry.peek("run-chat-send")).toBeUndefined();
expect(clearAgentRunContext).toHaveBeenCalledWith("run-chat-send");
expect(agentRunSeq.has("run-chat-send")).toBe(false);
});
it("suppresses chat and node session events for non-control-UI-visible runs", () => {
const { broadcast, nodeSendToSession, handler } = createHarness({
resolveSessionKeyForRun: () => "session-hidden",