Error Handling
Failures are normal. Design for classification, recovery, and operator visibility — not only try/catch cosmetics.
Workflow
- Enumerate failure modes (validation, not found, conflict, auth, dependency down, timeout, partial success).
- Separate expected domain errors from programmer bugs.
- Define user-visible messages vs internal detail (never leak secrets).
- Retries only for safe/idempotent operations with backoff and caps.
- Specify observability: structured logs, metrics, traces, correlation IDs.
- Document partial failure and compensation for multi-step workflows.
Output format
## Error design: <component>
### Taxonomy
| Kind | Example | Retry? | User message | Operator signal |
### Boundaries
Where errors are caught and translated.
### Retry / timeout policy
…
### Propagation
HTTP/RPC codes or typed errors callers see.
Rules
- Distinguish validation from infrastructure failures.
- Never retry non-idempotent writes without idempotency keys.
- Prefer explicit error types/codes over string matching.
- Map to stable public statuses; avoid silent 200-with-error unless pre-existing API law.
- Include cleanup for partial side effects.
- Fail closed on authorization uncertainty.
Edge cases
- Queues: poison messages, dead-letter, visibility timeouts.
- Fan-out: partial success reporting.
- Libraries: do not swallow exceptions to "keep going" without policy.