← ClaudeAtlas

principle-error-handlinglisted

Error handling principles — errors as values vs exceptions, error classification (transient/permanent/programmer), wrapping and context chains, sentinel vs typed vs coded errors, retry with exponential backoff and jitter, timeouts and deadlines, circuit breakers and bulkheads, log-once boundary discipline. Auto-load when discussing errors as values, Result type, exception handling, retry, exponential backoff, jitter, circuit breaker, fail fast, fail soft, idempotent retry, error wrapping, timeouts, or deadlines.
lugassawan/swe-workbench · ★ 2 · Code & Development · score 68
Install: claude install-skill lugassawan/swe-workbench
# Error Handling Errors are part of the contract. Handling them is not defensive programming — it is the design. ## Errors as Values vs Exceptions Use the language's native error style; don't fight it. - **Go** `error` values, **Rust** `Result<T, E>`, **TypeScript** typed unions: errors are explicit return paths, visible in signatures, handled by callers. - Exceptions (Java, Python, C#) work best for truly unexpected conditions — programmer errors, not business failures. - Reserve `panic` / `throw` / unchecked exceptions for unrecoverable programmer errors. Expected failures (network timeout, not found) must be value-level errors. ## Classify Before Handling Not all errors deserve the same response. - **Transient** — network blip, timeout, lock contention: retry with backoff (fail soft — degrade gracefully while recovering). - **Permanent** — bad input, not found, permission denied: fail fast — surface immediately to the caller, never retry. - **Programmer** — nil deref, index out of bounds, invariant violated: panic/crash, fix the code. - Misclassifying a permanent error as transient wastes retry budget and delays the caller. ## Wrap, Don't Swallow At each layer boundary, add context to the error and preserve the original cause for downstream inspection. - Go: `fmt.Errorf("loading user config: %w", err)` — `%w` preserves `errors.Is` / `errors.As` traversal. - Rust: `anyhow::Context` / `.with_context(|| ...)` — attach human-readable context without losing the source. -