fix(comment-checker): add 30s hard timeout to CLI spawn
If the comment-checker binary hangs, Promise.race with a 30s timeout
kills the process and returns a safe fallback {hasComments: false}.
This commit is contained in:
parent
a8681a9ffe
commit
ea1b22454d
@ -164,6 +164,8 @@ export async function runCommentChecker(input: HookInput, cliPath?: string, cust
|
|||||||
const jsonInput = JSON.stringify(input)
|
const jsonInput = JSON.stringify(input)
|
||||||
debugLog("running comment-checker with input:", jsonInput.substring(0, 200))
|
debugLog("running comment-checker with input:", jsonInput.substring(0, 200))
|
||||||
|
|
||||||
|
let didTimeout = false
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const args = [binaryPath, "check"]
|
const args = [binaryPath, "check"]
|
||||||
if (customPrompt) {
|
if (customPrompt) {
|
||||||
@ -176,13 +178,39 @@ export async function runCommentChecker(input: HookInput, cliPath?: string, cust
|
|||||||
stderr: "pipe",
|
stderr: "pipe",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
let timeoutId: ReturnType<typeof setTimeout> | null = null
|
||||||
|
const timeoutPromise = new Promise<"timeout">(resolve => {
|
||||||
|
timeoutId = setTimeout(() => {
|
||||||
|
didTimeout = true
|
||||||
|
debugLog("comment-checker timed out after 30s; killing process")
|
||||||
|
try {
|
||||||
|
proc.kill()
|
||||||
|
} catch (err) {
|
||||||
|
debugLog("failed to kill comment-checker process:", err)
|
||||||
|
}
|
||||||
|
resolve("timeout")
|
||||||
|
}, 30_000)
|
||||||
|
})
|
||||||
|
|
||||||
|
try {
|
||||||
// Write JSON to stdin
|
// Write JSON to stdin
|
||||||
proc.stdin.write(jsonInput)
|
proc.stdin.write(jsonInput)
|
||||||
proc.stdin.end()
|
proc.stdin.end()
|
||||||
|
|
||||||
const stdout = await new Response(proc.stdout).text()
|
const stdoutPromise = new Response(proc.stdout).text()
|
||||||
const stderr = await new Response(proc.stderr).text()
|
const stderrPromise = new Response(proc.stderr).text()
|
||||||
const exitCode = await proc.exited
|
const exitCodePromise = proc.exited
|
||||||
|
|
||||||
|
const raceResult = await Promise.race([
|
||||||
|
Promise.all([stdoutPromise, stderrPromise, exitCodePromise] as const),
|
||||||
|
timeoutPromise,
|
||||||
|
])
|
||||||
|
|
||||||
|
if (raceResult === "timeout") {
|
||||||
|
return { hasComments: false, message: "" }
|
||||||
|
}
|
||||||
|
|
||||||
|
const [stdout, stderr, exitCode] = raceResult
|
||||||
|
|
||||||
debugLog("exit code:", exitCode, "stdout length:", stdout.length, "stderr length:", stderr.length)
|
debugLog("exit code:", exitCode, "stdout length:", stdout.length, "stderr length:", stderr.length)
|
||||||
|
|
||||||
@ -198,7 +226,15 @@ export async function runCommentChecker(input: HookInput, cliPath?: string, cust
|
|||||||
// Error case
|
// Error case
|
||||||
debugLog("unexpected exit code:", exitCode, "stderr:", stderr)
|
debugLog("unexpected exit code:", exitCode, "stderr:", stderr)
|
||||||
return { hasComments: false, message: "" }
|
return { hasComments: false, message: "" }
|
||||||
|
} finally {
|
||||||
|
if (timeoutId !== null) {
|
||||||
|
clearTimeout(timeoutId)
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
if (didTimeout) {
|
||||||
|
return { hasComments: false, message: "" }
|
||||||
|
}
|
||||||
debugLog("failed to run comment-checker:", err)
|
debugLog("failed to run comment-checker:", err)
|
||||||
return { hasComments: false, message: "" }
|
return { hasComments: false, message: "" }
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user