fix: address pr-bug-scan validated finding from #6952

throwNodeNotFound() now re-raises AbortError when the shared signal is aborted, so a signal-cancelled node probe no longer launders into 'Node.js not found'; sequential fallback runs.
This commit is contained in:
orca-bug-scan-bot
2026-07-02 20:51:03 -07:00
parent e6ca3087c5
commit 488e3733b8
2 changed files with 31 additions and 4 deletions
@@ -331,6 +331,25 @@ describe('resolveRemoteNodePath', () => {
).rejects.toBe(sessionLimitError)
})
it('surfaces an AbortError instead of not-found when the shared signal is aborted', async () => {
// Why: in concurrent bootstrap a sibling probe aborts this resolution via
// the shared signal. Each strategy catch swallows the injected AbortError,
// so without re-raising it here the resolver would launder cancellation
// into a fatal "Node.js not found" and defeat the sequential fallback.
const controller = new AbortController()
const abortError = Object.assign(new Error('SSH operation was cancelled'), {
name: 'AbortError'
})
execCommandMock.mockImplementation(() => {
controller.abort()
return Promise.reject(abortError)
})
await expect(
resolveRemoteNodePath(conn, undefined, { signal: controller.signal })
).rejects.toMatchObject({ name: 'AbortError' })
})
it('throws when every candidate across both strategies is below the minimum', async () => {
execCommandMock
.mockResolvedValueOnce('/old/node\n') // path probe
+12 -4
View File
@@ -1,5 +1,5 @@
import type { SshConnection } from './ssh-connection'
import { shellEscape } from './ssh-connection-utils'
import { createSshOperationAbortError, shellEscape } from './ssh-connection-utils'
import type { RemoteHostPlatform } from './ssh-remote-platform'
import { isWindowsRemoteHost, normalizeWindowsRemotePath } from './ssh-remote-platform'
import { powerShellCommand } from './ssh-remote-powershell'
@@ -47,7 +47,7 @@ export async function resolveRemoteNodePath(
return loginShellPath
}
throwNodeNotFound()
throwNodeNotFound(options)
}
// Probe the on-disk install directories of every common Node version manager
@@ -245,10 +245,18 @@ async function resolveRemoteWindowsNodePath(
// Fall through to the shared error below.
}
throwNodeNotFound()
throwNodeNotFound(options)
}
function throwNodeNotFound(): never {
function throwNodeNotFound(options?: RemoteNodeResolutionOptions): never {
// Why: when a sibling bootstrap probe aborts this resolution via the shared
// signal, the strategy catch-blocks swallow the injected AbortError and fall
// through to here. Surfacing "Node.js not found" would launder a cancellation
// into a fatal non-session failure, defeating the concurrent-bootstrap
// sequential fallback. Re-raise the abort so callers classify it correctly.
if (options?.signal?.aborted) {
throw createSshOperationAbortError()
}
throw new Error(
'Node.js not found on remote host. Orca relay requires Node.js 18+. ' +
'Install Node.js on the remote and try again.'