Skip to content

Commit d9549d1

Browse files
greynewellclaude
andcommitted
fix: pass --timeout to CLI instead of unreliable Promise.race
Promise.race rejected the promise but left the subprocess running. The CLI now enforces the deadline via context cancellation, which exits cleanly and propagates the timeout error through getExecOutput. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 40fd8c2 commit d9549d1

2 files changed

Lines changed: 11 additions & 15 deletions

File tree

dist/index.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30054,14 +30054,15 @@ async function runDeadCodeAnalysis(opts) {
3005430054
for (const pattern of opts.ignorePatterns) {
3005530055
args.push('--ignore', pattern);
3005630056
}
30057+
// Let the CLI enforce the timeout via context deadline so the process exits cleanly.
30058+
if (opts.timeoutSeconds > 0) {
30059+
args.push('--timeout', String(opts.timeoutSeconds));
30060+
}
3005730061
core.info(`Running: supermodel ${args.join(' ')}`);
30058-
// Wrap in a timeout promise since @actions/exec does not expose a timeout option.
30059-
const execPromise = exec.getExecOutput('supermodel', args, {
30062+
const { stdout } = await exec.getExecOutput('supermodel', args, {
3006030063
env: processEnv({ SUPERMODEL_API_KEY: opts.apiKey }),
3006130064
ignoreReturnCode: false,
3006230065
});
30063-
const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error(`Analysis timed out after ${opts.timeoutSeconds}s`)), opts.timeoutSeconds * 1000));
30064-
const { stdout } = await Promise.race([execPromise, timeoutPromise]);
3006530066
return JSON.parse(stdout.trim());
3006630067
}
3006730068
async function getChangedFiles(token) {

src/index.ts

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,23 +40,18 @@ async function runDeadCodeAnalysis(opts: {
4040
args.push('--ignore', pattern);
4141
}
4242

43+
// Let the CLI enforce the timeout via context deadline so the process exits cleanly.
44+
if (opts.timeoutSeconds > 0) {
45+
args.push('--timeout', String(opts.timeoutSeconds));
46+
}
47+
4348
core.info(`Running: supermodel ${args.join(' ')}`);
4449

45-
// Wrap in a timeout promise since @actions/exec does not expose a timeout option.
46-
const execPromise = exec.getExecOutput('supermodel', args, {
50+
const { stdout } = await exec.getExecOutput('supermodel', args, {
4751
env: processEnv({ SUPERMODEL_API_KEY: opts.apiKey }),
4852
ignoreReturnCode: false,
4953
});
5054

51-
const timeoutPromise = new Promise<never>((_, reject) =>
52-
setTimeout(
53-
() => reject(new Error(`Analysis timed out after ${opts.timeoutSeconds}s`)),
54-
opts.timeoutSeconds * 1000
55-
)
56-
);
57-
58-
const { stdout } = await Promise.race([execPromise, timeoutPromise]);
59-
6055
return JSON.parse(stdout.trim()) as DeadCodeResult;
6156
}
6257

0 commit comments

Comments
 (0)