principle-error-handling
Installation
SKILL.md
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
errorvalues, RustResult<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.