← ClaudeAtlas

go-error-handlinglisted

Use when writing, reviewing, or refactoring error handling in Go — wrapping with %w, sentinel vs typed errors, errors.Is/errors.As, when panic is acceptable, error message style, and mapping domain errors to transport codes (HTTP/gRPC). Triggers on any Go code that returns, wraps, logs, or inspects errors.
Markuysa/agent-skills · ★ 0 · AI & Automation · score 70
Install: claude install-skill Markuysa/agent-skills
# Go error handling Errors are values and part of the API contract. Decide deliberately what a caller is allowed to *do* with each error, then pick the mechanism that supports it. ## The decision table | Caller needs to… | Use | Caller inspects with | | --- | --- | --- | | Nothing — just report it | `fmt.Errorf("...: %w", err)` | nothing | | Branch on a known condition | sentinel: `var ErrNotFound = errors.New("not found")` | `errors.Is` | | Read structured data off the failure | typed: `type ValidationError struct{ Field string }` | `errors.As` | | Nothing, ever — the process is broken | `panic` | — | If you cannot name what the caller does with the distinction, do not create it. An unexported wrapped error is cheaper than a new exported sentinel you must support forever. ## Rules **Wrap with `%w`, add context the caller doesn't have.** ```go // bad — loses the cause, message repeats the function name if err != nil { return fmt.Errorf("getUser failed: %v", err) } // good — preserves the chain, adds the identifier that was in scope if err != nil { return fmt.Errorf("load user %s: %w", id, err) } ``` Use `%v` (not `%w`) deliberately when you want to *stop* the chain — typically at a package boundary where the inner error is an implementation detail you refuse to make part of your API. **Message style.** Lowercase, no trailing punctuation, no "failed to" / "error while". Messages concatenate into a chain, so each segment is a noun phrase of what was being done