Skip to content

Commit 803e4d5

Browse files
SunnyShu0925claude
andcommitted
[AI] fix(gateway): log terminal session persistence failures at the owner catch
Log rejected persistGatewaySessionLifecycleEvent at the server-chat persistence owner boundary instead of in cleanup consumers. The owner catch already broadcasts a fallback session snapshot on failure; adding log.error here gives operators visibility into session-store write failures with a single diagnostic site that cannot double-report. Related to #97795 Co-Authored-By: Claude Opus 4.8 <[email protected]>
1 parent 68ead4d commit 803e4d5

2 files changed

Lines changed: 18 additions & 1 deletion

File tree

src/gateway/server-chat.agent-events.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ vi.mock("./session-utils.js", () => ({
3838
})),
3939
}));
4040

41+
const { mockLogError } = vi.hoisted(() => ({ mockLogError: vi.fn() }));
42+
vi.mock("../logging/subsystem.js", () => ({
43+
createSubsystemLogger: vi.fn(() => ({ error: mockLogError })),
44+
}));
45+
4146
import { getRuntimeConfig } from "../config/io.js";
4247
import { resolveHeartbeatVisibility } from "../infra/heartbeat-visibility.js";
4348
import {
@@ -69,6 +74,7 @@ describe("agent event handler", () => {
6974
});
7075
vi.mocked(loadGatewaySessionRow).mockReset().mockReturnValue(null);
7176
persistGatewaySessionLifecycleEventMock.mockReset().mockResolvedValue(undefined);
77+
mockLogError.mockReset();
7278
resetAgentRunContextForTest();
7379
});
7480

@@ -2521,6 +2527,11 @@ describe("agent event handler", () => {
25212527
abortedLastRun: false,
25222528
});
25232529
expect(markTrackedRunTerminalPersisted).not.toHaveBeenCalled();
2530+
expect(mockLogError).toHaveBeenCalledWith(
2531+
expect.stringContaining(
2532+
"gateway: failed to persist terminal session lifecycle event for run run-failed-write: Error: disk full",
2533+
),
2534+
);
25242535
});
25252536

25262537
it("does not clear a same-id retry when an old restart terminal arrives", () => {

src/gateway/server-chat.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@ import { getRuntimeConfig } from "../config/io.js";
99
import { type AgentEventPayload, getAgentRunContext } from "../infra/agent-events.js";
1010
import { detectErrorKind, type ErrorKind } from "../infra/errors.js";
1111
import { resolveHeartbeatVisibility } from "../infra/heartbeat-visibility.js";
12+
import { createSubsystemLogger } from "../logging/subsystem.js";
1213
import { isAcpSessionKey, isSubagentSessionKey } from "../sessions/session-key-utils.js";
14+
15+
const log = createSubsystemLogger("gateway/server-chat");
1316
import { resolveAssistantEventPhase } from "../shared/chat-message-content.js";
1417
import { setSafeTimeout } from "../utils/timer-delay.js";
1518
import {
@@ -708,7 +711,10 @@ export function createAgentEventHandler({
708711
markPersisted();
709712
broadcastSessionChange();
710713
})
711-
.catch(() => {
714+
.catch((err: unknown) => {
715+
log.error(
716+
`gateway: failed to persist terminal session lifecycle event for run ${evt.runId}: ${String(err)}`,
717+
);
712718
// Persistence recovery remains tracked by the controller entry, but
713719
// subscribers still need a terminal projection instead of hanging.
714720
broadcastSessionChange(evt);

0 commit comments

Comments
 (0)