Skip to content

Commit 0eb3026

Browse files
recuu-pfegclaude
andcommitted
fix: improve error handling for critical operations
- Pre-action failure now resets task to todo before skipping - Sprint completion and tag push errors log full stack traces - Add explanatory comments to acceptable catch blocks Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent c35d64e commit 0eb3026

2 files changed

Lines changed: 19 additions & 3 deletions

File tree

src/cli.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,12 @@ async function runLoop(cliArgs: CliArgs, runner: AgentRunner): Promise<void> {
224224
};
225225

226226
try { await executeActions(agentTemplate.pre_actions, actionCtx, "pre"); }
227-
catch (err) { logError(CLI_ERR.ACTION_FAILED, `Pre-actions failed: ${err}`, { taskId: task.id, phase: "pre" }, err); ui.error(`[task] Pre-actions failed: ${err}`); continue; }
227+
catch (err) {
228+
logError(CLI_ERR.ACTION_FAILED, `Pre-actions failed: ${err}`, { taskId: task.id, phase: "pre" }, err);
229+
ui.error(`[task] Pre-actions failed: ${err}`);
230+
try { await api.updateTask(task.id, { status: "todo" } as Partial<Task>); } catch { /* non-fatal: reset task status */ }
231+
continue;
232+
}
228233

229234
const contextNotes = (task as Record<string, unknown>).context_notes as string | undefined;
230235
const fullDescription = [task.description, contextNotes].filter(Boolean).join("\n\n") || undefined;
@@ -485,7 +490,12 @@ async function handleSprintComplete(apiUrl: string, apiKey: string, push: boolea
485490
if (sprint.status !== "completed") {
486491
s.start(`Completing sprint #${sprint.number}...`);
487492
try { await api.completeSprint(sprint.number); s.stop(`Sprint #${sprint.number} completed`); }
488-
catch (err) { s.stop("Failed"); ui.error(`${err}`); process.exit(1); }
493+
catch (err) {
494+
s.stop("Failed");
495+
logError(CLI_ERR.ACTION_FAILED, `Sprint completion failed`, { sprintNumber: sprint.number }, err);
496+
ui.error(`Sprint completion failed: ${err instanceof Error ? err.message : err}`);
497+
process.exit(1);
498+
}
489499
} else { ui.info(`Sprint #${sprint.number} already completed`); }
490500

491501
const tagName = `sprint-${sprint.number}`;
@@ -501,7 +511,11 @@ async function handleSprintComplete(apiUrl: string, apiKey: string, push: boolea
501511

502512
if (push) {
503513
try { execSync(`git push origin "${tagName}"`, { stdio: "inherit" }); ui.step(`Pushed ${tagName}`); }
504-
catch (err) { ui.error(`Failed to push tag: ${err}`); process.exit(1); }
514+
catch (err) {
515+
logError(CLI_ERR.ACTION_FAILED, `Failed to push tag ${tagName}`, { tagName }, err);
516+
ui.error(`Failed to push tag: ${err instanceof Error ? err.message : err}`);
517+
process.exit(1);
518+
}
505519
}
506520
ui.outro(`Sprint #${sprint.number} complete`);
507521
}

src/runner.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,8 +220,10 @@ export class AgentRunner {
220220
stopDockerAgent(managed.agent.config.name, managed.agent.config.taskId);
221221
} else if (managed.process.pid) {
222222
try {
223+
// Try killing entire process group first
223224
process.kill(-managed.process.pid, "SIGTERM");
224225
} catch {
226+
// Group kill may fail (e.g. no process group); fall back to individual process
225227
managed.process.kill("SIGTERM");
226228
}
227229
} else {

0 commit comments

Comments
 (0)