Files
goplt/docs/content/adr/0008-error-handling-strategy.md

1.8 KiB

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:
    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