-
Notifications
You must be signed in to change notification settings - Fork 0
Flatten recovery.ts — eliminate recovery-of-recovery nesting pattern #178
Copy link
Copy link
Closed
Description
Problem
recovery.ts (132 lines) has 9 try blocks, 9 catch blocks. The core issue: recovery code has its own recovery code. recoverOrFailTask() has try/catch around every API call, and each catch has its own error handling. This creates deeply nested code that's hard to follow.
What to do
1. Create a safeLota() helper
Instead of try/catch around every lota() call:
async function safeLota(method: string, path: string, body?: object): Promise<{ ok: boolean; data?: unknown; error?: string }> {
try {
const data = await lota(method, path, body);
return { ok: true, data };
} catch (e) {
return { ok: false, error: (e as Error).message };
}
}2. Flatten recoverOrFailTask() (lines 56-102)
Current: 4 try/catch blocks, 2 levels of nesting.
Refactor to sequential checks:
async function recoverOrFailTask(task, details, config): Promise<void> {
const retryCount = task.retries ?? 0;
if (retryCount < 3) {
const nextRetry = retryCount + 1;
log(`Recovering task #${task.id} (retry ${nextRetry}/3)`);
const metaOk = await safeLota("PATCH", `/tasks/${task.id}/meta`, { retries: nextRetry });
const statusOk = await safeLota("POST", `/tasks/${task.id}/status`, { status: "assigned" });
const commentOk = await safeLota("POST", `/tasks/${task.id}/comment`, { content: `...` });
if (!metaOk.ok || !statusOk.ok) {
err(`Failed to recover task #${task.id}: ${metaOk.error || statusOk.error}`);
return;
}
await safeLota(/* telegram */);
} else {
// ... same flat pattern for failure case
}
// Worktree cleanup
if (details.workspace) {
const wsPath = resolveWorkspacePath(details.workspace);
if (wsPath && existsSync(wsPath)) cleanStaleWorktrees(wsPath);
}
}3. Flatten checkRuntimeStaleTasks() (lines 106-131)
Current: 2 try/catch blocks.
Refactor:
async function checkRuntimeStaleTasks(config): Promise<void> {
const result = await safeLota("GET", "/tasks?status=in-progress");
if (!result.ok) { dim(`Runtime stale-task check failed: ${result.error}`); return; }
const tasks = result.data as StaleTask[];
for (const task of tasks.filter(...)) {
// ... flat sequential calls
}
}4. Separate Telegram calls
The Telegram try/catch blocks (lines 76-77, 89-90) are especially ugly — a failed notification shouldn't need its own catch. tgSend should handle its own errors internally (or safeLota pattern).
Check if tgSend already handles errors. If not, make it safe internally.
Target metrics
- try blocks: 9 → 1 (only inside safeLota)
- catch blocks: 9 → 1
- Nesting depth: 3-4 → 1-2
- Lines: ~132 → ~90-100
Files
src/recovery.ts— refactorsrc/telegram.ts— check if tgSend needs to be made safe internally
Acceptance
- No nested try/catch
- All API calls use safeLota pattern
- Same recovery behavior (retry 3x then fail)
- Telegram failures don't create nested catch blocks
Reactions are currently unavailable