# ADR-0008: Error Handling Strategy

## Status
Accepted

## Context
Go's error handling philosophy requires explicit error checking. We need a consistent approach for:
- Error creation and wrapping
- Error propagation
- Error classification (domain vs infrastructure)
- Error reporting (logging, monitoring)
- HTTP error responses

## Decision
Adopt a **wrapped error pattern** with **structured error types**:

1. **Error Wrapping**: Use `fmt.Errorf("context: %w", err)` for error wrapping
2. **Error Types**: Define custom error types for domain errors
3. **Error Classification**: Distinguish between:
   - Domain errors (business logic failures)
   - Infrastructure errors (external system failures)
   - Validation errors (input validation failures)
4. **Error Context**: Always wrap errors with context about where they occurred

**Rationale:**
- Follows Go 1.13+ error wrapping best practices
- Enables error inspection with `errors.Is()` and `errors.As()`
- Maintains error chains for debugging
- Allows structured error handling

## Consequences

### Positive
- Full error traceability through call stack
- Can inspect and handle specific error types
- Better debugging with error context
- Aligns with Go best practices

### Negative
- Requires discipline to wrap errors consistently
- Can be verbose in some cases

### Implementation Notes
- Always wrap errors: `return nil, fmt.Errorf("failed to load config: %w", err)`
- Create error types for domain errors:
  ```go
  type ConfigError struct {
      Key   string
      Cause error
  }
  func (e *ConfigError) Error() string { ... }
  func (e *ConfigError) Unwrap() error { return e.Cause }
  ```
- Use `errors.Is()` and `errors.As()` for error checking
- Log errors with context before returning
- Map domain errors to HTTP status codes in handlers

