mirror of
https://github.com/OpenRouterTeam/spawn.git
synced 2026-05-19 16:39:50 +00:00
fix: add timeout protection to uploadFile across all SSH-based clouds (#2298)
All four SSH-based uploadFile functions (Hetzner, DO, AWS, GCP) used `await proc.exited` on SCP subprocesses without any timeout guard. If SCP hangs due to a network issue, the CLI hangs indefinitely. This adds the same killWithTimeout pattern already used by runServer and runServerCapture in these same files: a 120-second timeout that kills the SCP process if it stalls. Agent: code-health Co-authored-by: B <6723574+louisgv@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
7bebc6558f
commit
1991ffcb15
5 changed files with 32 additions and 12 deletions
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@openrouter/spawn",
|
||||
"version": "0.15.8",
|
||||
"version": "0.15.9",
|
||||
"type": "module",
|
||||
"bin": {
|
||||
"spawn": "cli.js"
|
||||
|
|
|
|||
|
|
@ -1140,8 +1140,13 @@ export async function uploadFile(localPath: string, remotePath: string): Promise
|
|||
],
|
||||
},
|
||||
);
|
||||
if ((await proc.exited) !== 0) {
|
||||
throw new Error(`upload_file failed for ${remotePath}`);
|
||||
const timer = setTimeout(() => killWithTimeout(proc), 120_000);
|
||||
try {
|
||||
if ((await proc.exited) !== 0) {
|
||||
throw new Error(`upload_file failed for ${remotePath}`);
|
||||
}
|
||||
} finally {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1126,9 +1126,14 @@ export async function uploadFile(localPath: string, remotePath: string, ip?: str
|
|||
],
|
||||
},
|
||||
);
|
||||
const exitCode = await proc.exited;
|
||||
if (exitCode !== 0) {
|
||||
throw new Error(`upload_file failed for ${remotePath}`);
|
||||
const timer = setTimeout(() => killWithTimeout(proc), 120_000);
|
||||
try {
|
||||
const exitCode = await proc.exited;
|
||||
if (exitCode !== 0) {
|
||||
throw new Error(`upload_file failed for ${remotePath}`);
|
||||
}
|
||||
} finally {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -948,9 +948,14 @@ export async function uploadFile(localPath: string, remotePath: string): Promise
|
|||
env: process.env,
|
||||
},
|
||||
);
|
||||
const exitCode = await proc.exited;
|
||||
if (exitCode !== 0) {
|
||||
throw new Error(`upload_file failed for ${remotePath}`);
|
||||
const timer = setTimeout(() => killWithTimeout(proc), 120_000);
|
||||
try {
|
||||
const exitCode = await proc.exited;
|
||||
if (exitCode !== 0) {
|
||||
throw new Error(`upload_file failed for ${remotePath}`);
|
||||
}
|
||||
} finally {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -608,9 +608,14 @@ export async function uploadFile(localPath: string, remotePath: string, ip?: str
|
|||
],
|
||||
},
|
||||
);
|
||||
const exitCode = await proc.exited;
|
||||
if (exitCode !== 0) {
|
||||
throw new Error(`upload_file failed for ${remotePath}`);
|
||||
const timer = setTimeout(() => killWithTimeout(proc), 120_000);
|
||||
try {
|
||||
const exitCode = await proc.exited;
|
||||
if (exitCode !== 0) {
|
||||
throw new Error(`upload_file failed for ${remotePath}`);
|
||||
}
|
||||
} finally {
|
||||
clearTimeout(timer);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue