fix: Ignore correct errors thrown when resizing or scrolling an exited pty (#11440)

This commit is contained in:
Mayur Vaid
2025-10-22 09:57:49 +05:30
committed by GitHub
parent c7243997f4
commit 2940b50811
2 changed files with 53 additions and 1 deletions

View File

@@ -291,6 +291,54 @@ describe('ShellExecutionService', () => {
expect(mockHeadlessTerminal.resize).toHaveBeenCalledWith(100, 40);
});
it('should not resize the pty if it is not active', async () => {
const isPtyActiveSpy = vi
.spyOn(ShellExecutionService, 'isPtyActive')
.mockReturnValue(false);
await simulateExecution('ls -l', (pty) => {
ShellExecutionService.resizePty(pty.pid!, 100, 40);
pty.onExit.mock.calls[0][0]({ exitCode: 0, signal: null });
});
expect(mockPtyProcess.resize).not.toHaveBeenCalled();
expect(mockHeadlessTerminal.resize).not.toHaveBeenCalled();
isPtyActiveSpy.mockRestore();
});
it('should ignore errors when resizing an exited pty', async () => {
const resizeError = new Error(
'Cannot resize a pty that has already exited',
);
mockPtyProcess.resize.mockImplementation(() => {
throw resizeError;
});
// We don't expect this test to throw an error
await expect(
simulateExecution('ls -l', (pty) => {
ShellExecutionService.resizePty(pty.pid!, 100, 40);
pty.onExit.mock.calls[0][0]({ exitCode: 0, signal: null });
}),
).resolves.not.toThrow();
expect(mockPtyProcess.resize).toHaveBeenCalledWith(100, 40);
});
it('should re-throw other errors during resize', async () => {
const otherError = new Error('Some other error');
mockPtyProcess.resize.mockImplementation(() => {
throw otherError;
});
await expect(
simulateExecution('ls -l', (pty) => {
ShellExecutionService.resizePty(pty.pid!, 100, 40);
pty.onExit.mock.calls[0][0]({ exitCode: 0, signal: null });
}),
).rejects.toThrow('Some other error');
});
it('should scroll the headless terminal', async () => {
await simulateExecution('ls -l', (pty) => {
pty.onData.mock.calls[0][0]('file1.txt\n');

View File

@@ -750,7 +750,11 @@ export class ShellExecutionService {
} catch (e) {
// Ignore errors if the pty has already exited, which can happen
// due to a race condition between the exit event and this call.
if (e instanceof Error && 'code' in e && e.code === 'ESRCH') {
if (
e instanceof Error &&
(('code' in e && e.code === 'ESRCH') ||
e.message === 'Cannot resize a pty that has already exited')
) {
// ignore
} else {
throw e;