fix: settle unavailable PTY process inspection

This commit is contained in:
Jinwoo-H
2026-08-25 05:34:34 -04:00
parent 25c9af4ed4
commit 6cc1c137ec
2 changed files with 43 additions and 2 deletions
@@ -9,6 +9,7 @@ import {
setLocalPtyProvider,
unregisterSshPtyProvider
} from './pty'
import { TerminalSessionOwnerUnverifiedError } from '../daemon/daemon-errors'
vi.mock('electron', () => import('./pty-ipc-mock-registry').then((m) => m.electronModuleMock()))
vi.mock('fs', () => import('./pty-ipc-mock-registry').then((m) => m.fsModuleMock()))
@@ -516,4 +517,31 @@ describe('registerPtyHandlers', () => {
unavailable: true
})
})
it('preserves unknown liveness while settling structured process inspection', async () => {
const unavailable = vi.fn(() => {
throw new TerminalSessionOwnerUnverifiedError('saved-pty')
})
registerPtyHandlers(mainWindow as never)
setLocalPtyProvider({
hasChildProcesses: unavailable,
getForegroundProcess: unavailable,
confirmForegroundProcess: unavailable,
inspectProcess: unavailable
} as never)
await expect(handlers.get('pty:hasChildProcesses')!(null, { id: 'saved-pty' })).rejects.toThrow(
TerminalSessionOwnerUnverifiedError
)
await expect(
handlers.get('pty:getForegroundProcess')!(null, { id: 'saved-pty' })
).rejects.toThrow(TerminalSessionOwnerUnverifiedError)
await expect(
handlers.get('pty:confirmForegroundProcess')!(null, { id: 'saved-pty' })
).rejects.toThrow(TerminalSessionOwnerUnverifiedError)
await expect(handlers.get('pty:inspectProcess')!(null, { id: 'saved-pty' })).resolves.toEqual({
foregroundProcess: null,
hasChildProcesses: false,
unavailable: true
})
})
})
+15 -2
View File
@@ -28,6 +28,7 @@ import {
settlePendingPaneSerializer
} from '../pane/serializer-state'
import { installPtyHasPtyIpc } from './has-pty'
import { TerminalSessionOwnerUnverifiedError } from '../../../daemon/daemon-errors'
export function installPtyInspectIpcHandlers(deps: {
store?: Store
@@ -212,15 +213,27 @@ export function installPtyInspectIpcHandlers(deps: {
ipcMain.handle('pty:inspectProcess', async (_event, args: { id: string }) => {
// Why: same routing hazard as pty:hasPty — an unroutable id must read as unavailable, not as a local-provider answer or a raised IPC error.
const unavailable = {
foregroundProcess: null,
hasChildProcesses: false,
unavailable: true as const
}
if (
typeof args?.id !== 'string' ||
!args.id ||
args.id.startsWith('remote:') ||
!hasPtyProviderForInspection(args.id)
) {
return { foregroundProcess: null, hasChildProcesses: false, unavailable: true as const }
return unavailable
}
try {
return await inspectPtyProviderProcessForRenderer(getProviderForPty(args.id), args.id)
} catch (error) {
if (error instanceof TerminalSessionOwnerUnverifiedError) {
return unavailable
}
throw error
}
return inspectPtyProviderProcessForRenderer(getProviderForPty(args.id), args.id)
})
ipcMain.handle(