diff --git a/src/shared/tmux/tmux-utils/pane-close.test.ts b/src/shared/tmux/tmux-utils/pane-close.test.ts index ca5d74684..b8d5d7887 100644 --- a/src/shared/tmux/tmux-utils/pane-close.test.ts +++ b/src/shared/tmux/tmux-utils/pane-close.test.ts @@ -170,7 +170,7 @@ describe("closeTmuxPane", () => { expect(spawnCalls).toHaveLength(0) }) - it("#given kill-pane fails #when closeTmuxPane called #then returns false", async () => { + it("#given kill-pane fails with unknown error #when closeTmuxPane called #then returns false", async () => { // given const closeTmuxPane = await loadCloseTmuxPane() queuedProcesses.push(createProcess(0), createProcess(1)) @@ -182,6 +182,30 @@ describe("closeTmuxPane", () => { expect(result).toBe(false) }) + it("#given pane already closed by Ctrl+C (kill-pane reports 'can't find pane') #when closeTmuxPane called #then returns true", async () => { + // given + const closeTmuxPane = await loadCloseTmuxPane() + queuedProcesses.push( + createProcess(0), + { + exited: Promise.resolve(1), + stdout: createClosedStream(), + stderr: new ReadableStream({ + start(controller) { + controller.enqueue(new TextEncoder().encode("can't find pane: %42\n")) + controller.close() + }, + }), + }, + ) + + // when + const result = await closeTmuxPane("%42") + + // then + expect(result).toBe(true) + }) + it("#given kill-pane stdout stream waits for drain #when closeTmuxPane called #then returns true once drainer consumes stdout", async () => { // given const closeTmuxPane = await loadCloseTmuxPane() diff --git a/src/shared/tmux/tmux-utils/pane-close.ts b/src/shared/tmux/tmux-utils/pane-close.ts index 76d9dd11b..e62e46296 100644 --- a/src/shared/tmux/tmux-utils/pane-close.ts +++ b/src/shared/tmux/tmux-utils/pane-close.ts @@ -46,11 +46,19 @@ export async function closeTmuxPane(paneId: string): Promise { killPaneProc.exited, ]) - if (exitCode !== 0) { - log("[closeTmuxPane] FAILED", { paneId, exitCode, stderr: stderr.trim() }) - } else { - log("[closeTmuxPane] SUCCESS", { paneId }) + const trimmedStderr = stderr.trim() + const paneAlreadyGone = exitCode !== 0 && /can't find pane/i.test(trimmedStderr) + + if (paneAlreadyGone) { + log("[closeTmuxPane] SUCCESS (pane already closed by Ctrl+C)", { paneId }) + return true } - return exitCode === 0 + if (exitCode !== 0) { + log("[closeTmuxPane] FAILED", { paneId, exitCode, stderr: trimmedStderr }) + return false + } + + log("[closeTmuxPane] SUCCESS", { paneId }) + return true }