Adopt a standard that prevents misleading state, lost root causes, and unhandled async failures—especially in recovery/timeout paths.
Rules: 1) Handle both rejection and exceptions in promise chains
.then(x, onError), also guard exceptions thrown inside x (setup/stream wiring/attach). Prefer .then(attach).catch(...) when attach can throw.2) Never leave critical async work unobserved
.then(...) without a .catch(...) when failure changes UI/state or invariants. Either await inside the existing try/catch, or attach an explicit catch that logs and/or reports state.3) Cleanup/cancel timers on the error path
4) Preserve error meaning; don’t silently widen retryability
5) Never “silently disable” safety
6) Route all async stream/write failures into the correct failure handler
Example: replace a fragile promise chain that can throw during attach
const handle = new SandboxedProcess();
void loadMxc()
.then((mxc) => mxc.spawn(/* ... */))
.then((sandboxed) => handle.attach(sandboxed))
.catch((error: unknown) => {
// Ensures both spawn rejection AND attach exceptions are handled.
const reason = error instanceof Error ? error.message : String(error);
handle.fail(new Error(`Sandbox failed: ${reason}`));
});
Example: avoid unhandled commit failures
try {
await this.say("checkpoint_created");
const commitHash = await this.checkpointTracker.commit();
await this.messageStateHandler.updateClineMessage(
/* index */, { lastCheckpointHash: commitHash }
);
} catch (e) {
Logger.warn("checkpoint commit failed", e);
// Preserve previous behavior: show that no hash is available without breaking the run.
}
Example: cancel observation timer on spawn failure
let timer: NodeJS.Timeout | undefined;
try {
timer = setTimeout(report, observationMs);
timer.unref?.();
const child = spawn(/* ... */);
// ...
} catch (e) {
if (timer) clearTimeout(timer);
// Emit only spawn failure; do not emit an exited:false runtime sample.
throw e;
}
Applying these rules consistently will reduce orphaned state, false telemetry, lost attribution (timeouts), and unhandled promise rejections across run/recovery/sandbox/plugin execution flows.