# Error Handling

Error discipline that preserves system integrity.

## Rules

1. **Errors are for callers, not for you.** If your function can fail, the caller decides what happens. Return the error. Don't log and swallow. Don't retry internally. The caller has context you don't.

2. **Typed errors, not strings.** `NotFound`, `ValidationError`, `RateLimitExceeded`. Each error type carries the information needed to handle it. A string message is for humans. A type is for code.

3. **Wrap, don't leak.** If a database query fails, the caller gets `DatabaseError`, not `PostgresConnectionRefused`. Internal details are internal. Wrap the low-level error in your domain type.

4. **No silent failures.** If something went wrong and you handled it, that handling is part of the system's behavior. Log it, trace it, count it. "It worked" and "it failed gracefully" are different outcomes.

5. **Fail at the boundary, recover at the boundary.** The edge of your system catches failures. The core assumes success. Don't pepper error handling through business logic — put it at the seams.

6. **Errors are not control flow.** If you're throwing to branch logic, use a different pattern. Errors are for unexpected situations. Expected alternatives are just different return values.

## What This Replaces

Try-catch everywhere and logging into the void. Error handling becomes a system-level concern, not a per-function afterthought.
