Awesome Reviewers expert instructions

domains / / cline/CLINE

Safe Startup Error Handling

For startup/OS-specific code paths, handle failures predictably: don’t panic on edge cases; when recovery is possible, retry with backoff; when you must fail, surface bounded, non-sensitive diagnostics.

raw .md Error Handling Rust

For startup/OS-specific code paths, handle failures predictably: don’t panic on edge cases; when recovery is possible, retry with backoff; when you must fail, surface bounded, non-sensitive diagnostics.

Apply this standard: 1) Avoid panics on invalid inputs

  • Validate invariants (e.g., non-empty work areas, valid coordinate ranges) before clamping/transforming.
  • If the invariant can’t be satisfied, return an error and keep the app running (or fall back to a safe behavior) rather than crashing.

2) Provide bounded, sanitized failure context

  • Any logs/diagnostics captured during startup must be:
    • bounded in count/size to prevent memory blowups
    • sanitized to avoid leaking secrets/tokens
  • Include exit status and a short diagnostic summary in the final error message.

3) Prefer graceful recovery over immediate failure

  • For readiness/endpoint publication, use a wait loop with a deadline.
  • If the process dies before publishing, respawn (paced with backoff) rather than failing the whole flow.
  • In process lifecycle code, treat “already exited” teardown cases as non-fatal.

Illustrative pattern (Rust-like pseudocode):

const MAX_LINES: usize = 32;
const MAX_LINE_LEN: usize = 1024;

fn sanitize_diagnostic(line: &str) -> String {
    // redact/omit known sensitive markers; keep output bounded
    let trimmed: String = line.chars().filter(|c| !c.is_control()).take(MAX_LINE_LEN).collect();
    if trimmed.to_lowercase().contains("token") {
        "[Sensitive startup diagnostic omitted]".to_string()
    } else {
        trimmed
    }
}

fn record_startup_failure(diags: &mut VecDeque<String>, line: &str) {
    if diags.len() == MAX_LINES { diags.pop_front(); }
    let line = sanitize_diagnostic(line);
    if !line.is_empty() { diags.push_back(line); }
}

fn ensure_ready_or_recover(wait_deadline: Instant, mut respawn: impl FnMut() -> Result<(), String>) -> Result<String, String> {
    while Instant::now() < wait_deadline {
        // check readiness...
        // if child exited early: respawn with backoff
        // continue waiting...
    }
    // return an error that includes bounded diagnostics + exit info
    Err("Startup failed: endpoint not published within timeout".to_string())
}

Result: users get a graceful failure (or recovery), developers get actionable context, and the app avoids catastrophic crashes from edge-case OS/input conditions.