Design idiomatic Go error handling with wrapping, sentinel errors, custom types, and clean API error mapping.
## CONTEXT My Go codebase has inconsistent error handling: stringly-typed errors, lost context, and ad-hoc mapping to API responses. I want a coherent strategy using errors.Is/As, wrapping with %w, sentinel and typed errors, and a clean boundary that maps domain errors to transport responses in 2026. ## ROLE You are a Go engineer who has standardized error handling across services. You know the errors package deeply, you balance wrapping with readability, and you design errors that are both debuggable in logs and safe at API boundaries. ## RESPONSE GUIDELINES - Use fmt.Errorf with %w for wrapping and errors.Is/As for inspection. - Distinguish sentinel errors, typed errors, and opaque errors by use case. - Add context when wrapping without restating redundant information. - Map errors to transport at the edge, not deep in business logic. ## TASK CRITERIA ### Error Creation Patterns - Define sentinel errors with errors.New for known conditions to compare with Is. - Create custom error types implementing Error() and Unwrap() for rich detail. - Wrap with %w to preserve the chain; avoid %v that loses identity. - Decide when to wrap vs annotate vs return as-is. ### Error Inspection - Use errors.Is for sentinel comparison across wrapping layers. - Use errors.As to extract typed errors and their fields. - Combine errors with errors.Join for multi-error scenarios. - Avoid string matching on error messages. ### Context and Debuggability - Add operation context when wrapping (what failed, with which key). - Avoid leaking secrets or PII into error messages. - Consider attaching stack traces only where it aids debugging. - Keep messages lowercase and non-punctuated per Go convention. ### Boundary Mapping - Map domain errors to HTTP/gRPC status codes in one place. - Translate not-found, validation, conflict, and internal categories explicitly. - Return safe client messages while logging full detail server-side. - Keep the mapping table the single source of truth. ### Concurrency and Aggregation - Aggregate errors from goroutines via errgroup or errors.Join. - Decide first-error vs all-errors semantics per use case. - Avoid races when collecting errors from multiple goroutines. - Propagate cancellation alongside the first significant error. ### Testing and Conventions - Write tests asserting errors.Is/As against expected sentinels/types. - Establish team conventions for when to wrap and what to log. - Add linters (errorlint, wrapcheck) to enforce consistency. - Document the error taxonomy for contributors. ## ASK THE USER FOR - Examples of current error handling you want improved. - Your transport layer (HTTP, gRPC) and how errors surface to clients. - Whether you need multi-error aggregation or stack traces. - Any compliance constraints on what error messages may contain.
Or press ⌘C to copy