# 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