From 2c911c3695202b652cb7985e7dc9d4033c6a2191 Mon Sep 17 00:00:00 2001 From: Jinjing <6427696+AmethystLiang@users.noreply.github.com> Date: Mon, 3 Aug 2026 19:39:17 -0700 Subject: [PATCH] fix(ssh): fix flaky test sync and add error code safety check Test was using tick-based Promise.resolve() loops which don't guarantee the async operation has started. Replace with signal-based synchronization that waits for the actual lease flush. Also add nullish-coalescing to error code check to prevent crashes if error is null or undefined. --- src/main/ipc/ssh.test.ts | 16 +++++++++++----- src/main/ssh/ssh-owner-recovery-retry.ts | 3 ++- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/main/ipc/ssh.test.ts b/src/main/ipc/ssh.test.ts index bea2164905d..39843b601c3 100644 --- a/src/main/ipc/ssh.test.ts +++ b/src/main/ipc/ssh.test.ts @@ -618,13 +618,19 @@ describe('SSH IPC handlers', () => { const detachFlush = new Promise((resolve) => { releaseDetach = resolve }) - mockStore.markSshRemotePtyLeasesAsync.mockImplementationOnce(() => detachFlush) + let signalEnteredDetach = (): void => {} + const enteredDetach = new Promise((resolve) => { + signalEnteredDetach = resolve + }) + mockStore.markSshRemotePtyLeasesAsync.mockImplementationOnce(() => { + signalEnteredDetach() + return detachFlush + }) const replacement = handlers.get('ssh:connect')!(null, { targetId: 'ssh-1' }) - // Why: let the replacement connect reach the flush before shutdown snapshots what to drain. - for (let tick = 0; tick < 10; tick++) { - await Promise.resolve() - } + // Why await the flush entry and not ticks: shutdown must not snapshot what to drain until the + // replacement connect is parked in the lease flush. + await enteredDetach expect(mockStore.markSshRemotePtyLeasesAsync).toHaveBeenCalledWith('ssh-1', 'detached') mockConnectionManager.disconnectAll.mockClear() diff --git a/src/main/ssh/ssh-owner-recovery-retry.ts b/src/main/ssh/ssh-owner-recovery-retry.ts index ea460f63d13..9449853acdb 100644 --- a/src/main/ssh/ssh-owner-recovery-retry.ts +++ b/src/main/ssh/ssh-owner-recovery-retry.ts @@ -46,7 +46,8 @@ export async function retrySshOwnerRecoveryWhilePublicationPending( return await attempt() } catch (error) { if ( - (error as { code?: unknown }).code !== PTY_CONSUMER_OWNER_RECOVERY_PENDING_ERROR || + (error as { code?: unknown } | null | undefined)?.code !== + PTY_CONSUMER_OWNER_RECOVERY_PENDING_ERROR || !gate.isCurrent() ) { throw error