mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-26 12:26:38 -06:00
fix(ui): surface rejected terminal actions (#124046)
Mark stale terminal tabs exited when the Gateway rejects input or resize, so operators see an actionable outcome instead of silently losing keystrokes.
This commit is contained in:
committed by
GitHub
parent
4b8ca98a94
commit
e68f3d8ad1
@@ -545,6 +545,29 @@ describe("TerminalConnection", () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it.each([
|
||||
["terminal.input", (conn: TerminalConnection) => conn.input("s1", "echo lost\n")],
|
||||
["terminal.resize", (conn: TerminalConnection) => conn.resize("s1", 120, 40)],
|
||||
] as const)("marks the session unavailable when %s rejects its live owner", async (_, act) => {
|
||||
const { client, conn } = makeHarness();
|
||||
const exits: unknown[] = [];
|
||||
await openSession(conn, { onExit: (info) => exits.push(info) });
|
||||
client.nextResponse = { ok: false };
|
||||
|
||||
await act(conn);
|
||||
|
||||
expect(exits).toEqual([
|
||||
{
|
||||
exitCode: null,
|
||||
signal: null,
|
||||
reason: "disconnected",
|
||||
error: "Terminal session is no longer available. Open a new terminal session.",
|
||||
},
|
||||
]);
|
||||
expect(conn.size).toBe(0);
|
||||
expect(client.listenerCount()).toBe(0);
|
||||
});
|
||||
|
||||
it("buffers output that races ahead of sink registration and replays it in order", async () => {
|
||||
const { client, conn } = makeHarness();
|
||||
const data: string[] = [];
|
||||
|
||||
@@ -612,11 +612,25 @@ export class TerminalConnection {
|
||||
}
|
||||
|
||||
async input(sessionId: string, data: string): Promise<void> {
|
||||
await this.client.request("terminal.input", { sessionId, data }).catch(() => undefined);
|
||||
await this.requestAction("terminal.input", sessionId, { sessionId, data });
|
||||
}
|
||||
|
||||
async resize(sessionId: string, cols: number, rows: number): Promise<void> {
|
||||
await this.client.request("terminal.resize", { sessionId, cols, rows }).catch(() => undefined);
|
||||
await this.requestAction("terminal.resize", sessionId, { sessionId, cols, rows });
|
||||
}
|
||||
|
||||
private async requestAction(method: string, sessionId: string, params: unknown): Promise<void> {
|
||||
const stream = this.streams.get(sessionId);
|
||||
const result = await this.client.request<{ ok: boolean }>(method, params).catch(() => null);
|
||||
if (result?.ok !== false || !stream || this.streams.get(sessionId) !== stream) {
|
||||
return;
|
||||
}
|
||||
this.deliverExit(sessionId, stream, {
|
||||
exitCode: null,
|
||||
signal: null,
|
||||
reason: "disconnected",
|
||||
error: "Terminal session is no longer available. Open a new terminal session.",
|
||||
});
|
||||
}
|
||||
|
||||
/** Closes a session server-side and drops its local stream state. */
|
||||
|
||||
Reference in New Issue
Block a user