← ClaudeAtlas

go-error-handlinglisted

Use when writing, wrapping, inspecting, or logging Go errors. Covers strategy choice (sentinel vs typed vs opaque), wrapping with %w/%v, errors.Is/As/Join, the log-or-return rule, error strings, and panic/recover boundaries. Apply proactively whenever a function returns or accepts an error, even if the user has not asked about error handling.
muratmirgun/gophers · ★ 6 · AI & Automation · score 84
Install: claude install-skill muratmirgun/gophers
# Go Error Handling Errors in Go are values. Treat them as part of the API: choose a strategy per failure mode, propagate with wrapping, inspect with `errors.Is`/`As`, and handle each error **exactly once**. ## Core Rules 1. **Errors are values, not exceptions.** Return them; do not panic across API boundaries. 2. **Handle each error exactly once.** *Either* log it *or* return it — never both. 3. **The caller decides what is exceptional.** Library code returns; binaries (or top-level handlers) decide whether to log, retry, or exit. 4. **Wrap only when you add real context.** A wrap that just repeats the function name is noise. Use `%w` to preserve identity; `%v` to deliberately hide an unstable type. ## Strategy Decision Pick the simplest strategy that meets the caller's needs: | Strategy | When to use | Example | |---|---|---| | **Opaque error** (default) | Caller only needs to know *something* failed | `errors.New("invalid input")` | | **Sentinel error** | Caller needs to test for a specific named condition | `io.EOF`, `sql.ErrNoRows` | | **Typed error** | Caller needs structured fields (path, code, retry-after) | `*os.PathError`, `*url.Error` | | **Joined errors** | A single operation produced several independent failures | `errors.Join(errA, errB)` | > Read [references/strategy-decision.md](references/strategy-decision.md) when the caller's needs are unclear or when migrating between strategies without breaking callers. ## Writing Errors ### Strings - **Lowercas