refactor: extract runSafely helper for try-catch-debug-continue pattern (#2611)
* refactor: extract runSafely helper for try-catch-debug-continue pattern
Reduces boilerplate in auto-post-unit.ts by extracting the repeated
try { op() } catch (e) { debugLog(ctx, { phase, error }) } pattern
into a reusable runSafely() helper in auto-utils.ts. Replaces 6
sequential blocks (github-sync, prune-bg-shell, browser-teardown,
worktree-sync, rewrite-docs-resolve, reactive-state-cleanup).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* ci: trigger rebuild after null-safety fix
* chore: trigger CI rebuild
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
dc378242bd
commit
c2aaf6ace8
2 changed files with 42 additions and 27 deletions
|
|
@ -47,6 +47,7 @@ import {
|
|||
} from "./post-unit-hooks.js";
|
||||
import { hasPendingCaptures, loadPendingCaptures } from "./captures.js";
|
||||
import { debugLog } from "./debug-logger.js";
|
||||
import { runSafely } from "./auto-utils.js";
|
||||
import type { AutoSession } from "./auto/session.js";
|
||||
|
||||
/** Unit types that only touch `.gsd/` internal state files (no code changes).
|
||||
|
|
@ -239,6 +240,7 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|||
|
||||
// Auto-commit
|
||||
if (s.currentUnit) {
|
||||
const unit = s.currentUnit;
|
||||
try {
|
||||
let taskContext: TaskCommitContext | undefined;
|
||||
|
||||
|
|
@ -297,64 +299,52 @@ export async function postUnitPreVerification(pctx: PostUnitContext, opts?: PreV
|
|||
}
|
||||
|
||||
// GitHub sync (non-blocking, opt-in)
|
||||
try {
|
||||
await runSafely("postUnit", "github-sync", async () => {
|
||||
const { runGitHubSync } = await import("../github-sync/sync.js");
|
||||
await runGitHubSync(s.basePath, s.currentUnit.type, s.currentUnit.id);
|
||||
} catch (e) {
|
||||
debugLog("postUnit", { phase: "github-sync", error: String(e) });
|
||||
}
|
||||
await runGitHubSync(s.basePath, unit.type, unit.id);
|
||||
});
|
||||
|
||||
// Prune dead bg-shell processes
|
||||
try {
|
||||
await runSafely("postUnit", "prune-bg-shell", async () => {
|
||||
const { pruneDeadProcesses } = await import("../bg-shell/process-manager.js");
|
||||
pruneDeadProcesses();
|
||||
} catch (e) {
|
||||
debugLog("postUnit", { phase: "prune-bg-shell", error: String(e) });
|
||||
}
|
||||
});
|
||||
|
||||
// Tear down browser between units to prevent Chrome process accumulation (#1733)
|
||||
try {
|
||||
await runSafely("postUnit", "browser-teardown", async () => {
|
||||
const { getBrowser } = await import("../browser-tools/state.js");
|
||||
if (getBrowser()) {
|
||||
const { closeBrowser } = await import("../browser-tools/lifecycle.js");
|
||||
await closeBrowser();
|
||||
debugLog("postUnit", { phase: "browser-teardown", status: "closed" });
|
||||
}
|
||||
} catch (e) {
|
||||
debugLog("postUnit", { phase: "browser-teardown", error: String(e) });
|
||||
}
|
||||
});
|
||||
|
||||
// Sync worktree state back to project root (skipped for lightweight sidecars)
|
||||
if (!opts?.skipWorktreeSync && s.originalBasePath && s.originalBasePath !== s.basePath) {
|
||||
try {
|
||||
syncStateToProjectRoot(s.basePath, s.originalBasePath, s.currentMilestoneId);
|
||||
} catch (e) {
|
||||
debugLog("postUnit", { phase: "worktree-sync", error: String(e) });
|
||||
}
|
||||
await runSafely("postUnit", "worktree-sync", () => {
|
||||
syncStateToProjectRoot(s.basePath, s.originalBasePath!, s.currentMilestoneId);
|
||||
});
|
||||
}
|
||||
|
||||
// Rewrite-docs completion
|
||||
if (s.currentUnit.type === "rewrite-docs") {
|
||||
try {
|
||||
await runSafely("postUnit", "rewrite-docs-resolve", async () => {
|
||||
await resolveAllOverrides(s.basePath);
|
||||
s.rewriteAttemptCount = 0;
|
||||
ctx.ui.notify("Override(s) resolved — rewrite-docs completed.", "info");
|
||||
} catch (e) {
|
||||
debugLog("postUnit", { phase: "rewrite-docs-resolve", error: String(e) });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Reactive state cleanup on slice completion
|
||||
if (s.currentUnit.type === "complete-slice") {
|
||||
try {
|
||||
const { milestone: mid, slice: sid } = parseUnitId(s.currentUnit.id);
|
||||
await runSafely("postUnit", "reactive-state-cleanup", async () => {
|
||||
const { milestone: mid, slice: sid } = parseUnitId(unit.id);
|
||||
if (mid && sid) {
|
||||
const { clearReactiveState } = await import("./reactive-graph.js");
|
||||
clearReactiveState(s.basePath, mid, sid);
|
||||
}
|
||||
} catch (e) {
|
||||
debugLog("postUnit", { phase: "reactive-state-cleanup", error: String(e) });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Post-triage: execute actionable resolutions
|
||||
|
|
|
|||
25
src/resources/extensions/gsd/auto-utils.ts
Normal file
25
src/resources/extensions/gsd/auto-utils.ts
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
// Shared utilities for the auto-loop modules (auto-post-unit, auto, etc.).
|
||||
|
||||
import { debugLog } from "./debug-logger.js";
|
||||
|
||||
/**
|
||||
* Run a non-fatal operation, logging any error via `debugLog` and continuing.
|
||||
*
|
||||
* Replaces the repeated try-catch-debugLog-continue boilerplate that wraps
|
||||
* operations whose failure should not abort the post-unit pipeline.
|
||||
*
|
||||
* @param context - The debugLog event name (e.g. "postUnit")
|
||||
* @param phase - The phase label attached to the debug entry
|
||||
* @param fn - The operation to execute (may be sync or async)
|
||||
*/
|
||||
export async function runSafely(
|
||||
context: string,
|
||||
phase: string,
|
||||
fn: () => Promise<void> | void,
|
||||
): Promise<void> {
|
||||
try {
|
||||
await fn();
|
||||
} catch (e) {
|
||||
debugLog(context, { phase, error: String(e) });
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue