mirror of
https://github.com/OpenRouterTeam/spawn.git
synced 2026-05-02 13:50:26 +00:00
refactor: extract helpers from execScript and _cloud_api_retry_loop (#821)
Reduce cyclomatic complexity in the two highest-scoring functions: - cli/src/commands.ts: Extract `handleUserInterrupt` and `runWithRetries` from `execScript` (complexity score 6 -> 2 for execScript, retry logic now independently testable) - shared/common.sh: Extract `_classify_api_result` and `_report_api_failure` from `_cloud_api_retry_loop` (complexity score 9 -> 4, removes duplicated error-classification logic from loop body) Agent: complexity-hunter Co-authored-by: A <6723574+louisgv@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
e73d6b9793
commit
4d3c54a11e
2 changed files with 67 additions and 45 deletions
|
|
@ -657,6 +657,37 @@ export function isRetryableExitCode(errMsg: string): boolean {
|
|||
return code === 255;
|
||||
}
|
||||
|
||||
function handleUserInterrupt(errMsg: string): void {
|
||||
if (!errMsg.includes("interrupted by user")) return;
|
||||
console.error();
|
||||
p.log.warn("Script interrupted (Ctrl+C).");
|
||||
p.log.warn("If a server was already created, it may still be running.");
|
||||
p.log.warn(` Check your cloud provider dashboard to stop or delete any unused servers.`);
|
||||
process.exit(130);
|
||||
}
|
||||
|
||||
async function runWithRetries(script: string, prompt?: string): Promise<string | undefined> {
|
||||
for (let attempt = 1; attempt <= MAX_RETRIES + 1; attempt++) {
|
||||
try {
|
||||
await runBash(script, prompt);
|
||||
return undefined; // success
|
||||
} catch (err) {
|
||||
const errMsg = getErrorMessage(err);
|
||||
handleUserInterrupt(errMsg);
|
||||
|
||||
if (attempt <= MAX_RETRIES && isRetryableExitCode(errMsg)) {
|
||||
const delay = RETRY_DELAYS[attempt - 1];
|
||||
p.log.warn(`Script failed (${errMsg}). Retrying in ${delay}s (attempt ${attempt + 1}/${MAX_RETRIES + 1})...`);
|
||||
await new Promise(r => setTimeout(r, delay * 1000));
|
||||
continue;
|
||||
}
|
||||
|
||||
return errMsg;
|
||||
}
|
||||
}
|
||||
return "Script failed after all retries";
|
||||
}
|
||||
|
||||
async function execScript(cloud: string, agent: string, prompt?: string, authHint?: string): Promise<void> {
|
||||
const url = `https://openrouter.ai/labs/spawn/${cloud}/${agent}.sh`;
|
||||
const ghUrl = `${RAW_BASE}/${cloud}/${agent}.sh`;
|
||||
|
|
@ -680,36 +711,10 @@ async function execScript(cloud: string, agent: string, prompt?: string, authHin
|
|||
// Non-fatal: don't block the spawn if history write fails
|
||||
}
|
||||
|
||||
let lastErr: string | undefined;
|
||||
for (let attempt = 1; attempt <= MAX_RETRIES + 1; attempt++) {
|
||||
try {
|
||||
await runBash(scriptContent, prompt);
|
||||
return; // success
|
||||
} catch (err) {
|
||||
const errMsg = getErrorMessage(err);
|
||||
if (errMsg.includes("interrupted by user")) {
|
||||
console.error();
|
||||
p.log.warn("Script interrupted (Ctrl+C).");
|
||||
p.log.warn("If a server was already created, it may still be running.");
|
||||
p.log.warn(` Check your cloud provider dashboard to stop or delete any unused servers.`);
|
||||
process.exit(130);
|
||||
}
|
||||
lastErr = errMsg;
|
||||
|
||||
// Only retry for potentially transient failures
|
||||
if (attempt <= MAX_RETRIES && isRetryableExitCode(errMsg)) {
|
||||
const delay = RETRY_DELAYS[attempt - 1];
|
||||
p.log.warn(`Script failed (${errMsg}). Retrying in ${delay}s (attempt ${attempt + 1}/${MAX_RETRIES + 1})...`);
|
||||
await new Promise(r => setTimeout(r, delay * 1000));
|
||||
continue;
|
||||
}
|
||||
|
||||
// Non-retryable or out of retries
|
||||
break;
|
||||
}
|
||||
const lastErr = await runWithRetries(scriptContent, prompt);
|
||||
if (lastErr) {
|
||||
reportScriptFailure(lastErr, cloud, agent, authHint, prompt);
|
||||
}
|
||||
|
||||
reportScriptFailure(lastErr!, cloud, agent, authHint, prompt);
|
||||
}
|
||||
|
||||
function runBash(script: string, prompt?: string): Promise<void> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue