go-error-handling
/go-error-handling
Podaje wzorce obsługi błędów w Go: opakowywanie, błędy sentinel, własne typy błędów i pakiet errors, oparte na Effective Go i Go Code Review Comments.
- Autor
- eduardo-sl ↗
- Repozytorium
- go-agent-skills ↗
- Licencja
- MIT
- Ostatnia zmiana repozytorium
- 15.10.2026
Ocena i bezpieczeństwo
- Pliki w paczce
- 2
- Skrypty
- 0
- Komentarze HTML
- 0
- Adresy URL w SKILL.md
- 0
Brak sygnałów. Repozytorium zmienione 15.10.2026, bez odwołań do wycofanych modeli i API.
MIT, otwarta: można używać i zmieniać, z zachowaniem informacji o autorze.
Co robi i kiedy
Podaje wzorce obsługi błędów w Go: opakowywanie, błędy sentinel, własne typy błędów i pakiet errors, oparte na Effective Go i Go Code Review Comments.
Wyzwalacze z opisu
Oryginalny opis (EN)
Go error handling patterns, wrapping, sentinel errors, custom error types, and the errors package. Grounded in Effective Go, Go Code Review Comments, and production-proven idioms. Use when implementing error handling, designing error types, debugging error chains, or reviewing error handling patterns. Trigger examples: "handle errors", "error wrapping", "custom error type", "sentinel errors", "errors.Is", "errors.As". Not for: panic/recover in middleware (go-api-design), test assertions (go-test-quality).
Jak działa
- 1. Error Decision Tree
- 2. Sentinel Errors
- 3. Custom Error Types
- 4. Error Wrapping
- 5. Handle Errors Exactly Once
- 6. Error Naming Conventions
- 7. Panic Rules
- 8. Error Checking Patterns
- 9. Errors at Boundaries
- Executable Verification
Podgląd SKILL.md
---
name: go-error-handling
description: >
Go error handling patterns, wrapping, sentinel errors, custom error types,
and the errors package. Grounded in Effective Go, Go Code Review Comments,
and production-proven idioms. Use when implementing error handling,
designing error types, debugging error chains, or reviewing error handling
patterns. Trigger examples: "handle errors", "error wrapping", "custom
error type", "sentinel errors", "errors.Is", "errors.As".
Not for: panic/recover in middleware (go-api-design), test assertions
(go-test-quality).
user-invocable: true
license: MIT
compatibility: Designed for Claude Code or similar AI coding agents working on Go projects. Requires the Go toolchain.
allowed-tools: Read Edit Write Glob Grep Bash(go:*) Bash(gofmt:*)
metadata:
author: eduardo-sl
version: "1.3.1"
---
# Go Error Handling
Go's explicit error handling is a feature, not a limitation.
These patterns ensure errors are informative, actionable, and properly propagated.
> Community default. A project skill or agent-config rule that explicitly
> supersedes `go-error-handling` takes precedence over this one.
Detailed reference material, loaded on demand:
- `references/patterns-and-boundaries.md` — checking patterns, `Is`
methods, translating errors at the HTTP boundary, low-cardinality logging,
the Go 1.27 vet check on `%w` with pointer errors.
Read a reference file only when the summary below is not enough.
## 1. Error Decision Tree
When creating or returning an error, follow this tree:
1. **Simple, no extra context needed?** → `errors.New("message")`
2. **Need to add context to existing error?** → `fmt.Errorf("doing X: %w", err)`
3. **Caller needs to detect this error?** → Sentinel `var` or custom type
4. **Error carries structured data?** → Custom type implementing `error`
5. **Propagating from downstream?** → Wrap with `%w` and add context
## 2. Sentinel Errors
Use package-level `var` for errors that callers need to check:
```go
// ✅ Good — exported sentinel error
var (
ErrNotFound = errors.New("user: not found")
ErrUnauthorized = errors.New("user: unauthorized")
)
// Naming convention: Err + Description
// Prefix with package context in the message
```
Callers check with `errors.Is`:
```go
if errors.Is(err, user.ErrNotFound) {
// handle not found
}
```
NEVER compare errors with `==`. Always use `errors.Is()`.
## 3. Custom Error Types
When errors need to carry structured information:
```go
type ValidationError struct {
Field string
Message string
}
func (e *ValidationError) Error() string {
return fmt.Sprintf("validation: field %s: %s", e.Field, e.Message)
}
// Callers extract it from the chain — Go 1.26+:
if valErr, ok := errors.AsType[*ValidationError](err); ok {
log.Printf("invalid field: %s", valErr.Field)
}
// Before Go 1.26:
var valErr *ValidationError
if errors.As(err, &valErr) {
log.Printf("invalid field: %s", valErr.Field)
}
```
A custom type that wraps a cause must expose it, or `errors.Is`/`errors.As`
stop at your type and never see the error underneath:
```go
type QueryError struct {
Query string
Err error
}
func (e *QueryError) Error() string { return "query " + e.Query + ": " + e.Err.Error() }
func (e *QueryError) Unwrap() error { return e.Err } // keeps the chain walkable
```
## 4. Error Wrapping
ALWAYS add context when propagating errors up the stack.
Use `%w` to preserve the error chain:
```go
// ✅ Good — context added, chain preserved
func getUser(id int64) (*User, error) {
row, err := db.QueryRow(ctx, query, id)
if err != nil {
return nil, fmt.Errorf("get user %d: %w", id, err)
}
// ...
}
// ❌ Bad — no context
return nil, err
// ❌ Bad — chain broken, callers can't errors.Is/As
return nil, fmt.Errorf("failed: %v", err)
```
### When NOT to use `%w`
Use `%v` instead of `%w` when you explicitly want to **break** the error chain,
preventing callers from depending on internal implementation errors:
```go
// Intentionally hiding internal DB error from public API
return nil, fmt.Errorf("user lookup failed: %v", err)
```
## 5. Handle Errors Exactly Once
An error should be either logged OR returned, never both:
```go
// ✅ Good — return the error, let caller decide
func loadConfig(path string) (*Config, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("load config %s: %w", path, err)
}
// ...
}
// ❌ Bad — log AND return (error handled twice)
func loadConfig(path string) (*Config, error) {
data, err := os.ReadFile(path)
if err != nil {
log.Printf("failed to read config: %v", err) // handled once
return nil, err // handled again
}
// ...
}
```
The rule: the component that *decides what to do* about the error is the one
that logs/metrics it. Everyone else wraps and returns.
## 6. Error Naming Conventions
```go
// Sentinel errors: Err prefix
var ErrNotFound = errors.New("not found")
// Error types: Error suffix
type NotFoundError struct { ... }
type ValidationError struct { ... }
// Error messages: lowercase, no punctuation, no "failed to" prefix
// Include context: "package: action: detail"
errors.New("auth: token expired")
fmt.Errorf("user: get by id %d: %w", id, err)
```
## 7. Panic Rules
Panic is NOT error handling. Use panic only when:
- Program initialization fails and cannot continue (`template.Must`, flag parsing)
- Programmer error that should never happen (violated invariant)
- Nil dereference that indicates a bug, not a runtime condition
In tests, use `t.Fatal` / `t.FailNow`, never `panic`.
In HTTP handlers and middleware, recover from panics at the boundary
to prevent one request from crashing the server.
## 8. Error Checking Patterns
- Scope the error to the `if` when nothing else needs it:
`if err := do(); err != nil { return fmt.Errorf("do: %w", err) }`.
- A deferred wrap on a named `err` result adds one prefix to every return
path of a long function.
- Collect independent failures (validation, parallel work) and return
`errors.Join(errs...)` — `errors.Is`/`As` see every joined error.
## 9. Errors at Boundaries
- **Publishing an error is a contract.** Inside the module, wrap with `%w`.
At a boundary you publish (an exported library API, an RPC), `%w` makes
the wrapped error part of your API; `%v` or a new error keeps it private.
- **Translate before it reaches a user.** Map domain errors to a status
and a stable message at the handler, and log the original once with its
chain. `err.Error()` in a response leaks SQL, paths and hostnames.
- **Keep logged messages low-cardinality.** The stable text is the message;
IDs, paths and counts go in structured attributes so the log backend can
group identical failures.
- **Panics do not cross goroutines.** A `recover` only works in the
goroutine that panicked — see go-concurrency-review.
- **Implement `Is(target error) bool`** on a type to let `errors.Is` match a
whole family of errors against one sentinel.
Examples for sections 8 and 9: `references/patterns-and-boundaries.md`.
## Executable Verification
After writing or reviewing error handling, run the linters that prove
the rules above (skip any that is not installed and note it):
```bash
go vet ./... # includes printf %w misuse
golangci-lint run --enable errcheck,errorlint # unchecked errors, %v-vs-%w,
# == comparisons on errors
```
## Verification Checklist
1. No `_` discarding errors (unless explicitly justified with comment)
2. Every `fmt.Errorf` wrapping uses `%w` (or `%v` with documented reason)
3. Sentinel errors use `var Err...` naming
4. Custom error types implement `error` interface
5. Callers use `errors.Is` / `errors.As` (`errors.AsType` on Go 1.26+), never `==` or type assertion
6. Custom types that wrap a cause implement `Unwrap() error`
7. No log-and-return patterns
8. Error messages are lowercase, contextual, chain-friendly
9. No `err.Error()` text in responses to users; logged messages are stable, details are attributes
Pliki w paczce (2)
- SKILL.md 8 KB
- references/patterns-and-boundaries.md 2 KB
Wersje
| Repozytorium | Wynik | Licencja |
|---|---|---|
| Ta strona · eduardo-sl/go-agent-skills | 100 | MIT |
| h0rn3t/golang-skills | 100 | Apache-2.0 |
| muratmirgun/gophers | 100 | MIT |
| muratmirgun/gophers | 100 | MIT |
| cxuu/golang-skills | 100 | Apache-2.0 |
| TheBushidoCollective/han | 95 | Apache-2.0 |
Identyczna treść występuje jeszcze w 1 innych folderach na GitHubie. Tu pokazujemy jedną, najlepiej ocenioną kopię.
Migawka bazy z 28.10.2026 · wersja paczki 9d5548f63405 (skrót SHA-256 całej paczki)
Pobrania w ostatnich 30 dniach: 0 · ranking
Zgłoś problem z tym skillem: szkodliwa treść, błędny opis albo prośba autora o usunięcie.
Podobne skille
- 100error-handling
Wdraża wzorce obsługi błędów w Go: opakowywanie błędów, błędy sentinel, własne typy błędów i konwencje propagacji. - 100go-error-management
Pomaga unikać typowych błędów obsługi błędów w Go: panic, opakowywanie błędów, errors.As i errors.Is, jednokrotna obsługa błędów oraz błędy z defer. - 100handling-rust-errors
Opisuje wzorce obsługi błędów HASH z crate error-stack: typy Result i Report, własne błędy, change_context, attach i implementację Error trait. - 95rust-error-handling
Dobiera strategię obsługi błędów w Ruście: Result, Option, panic, anyhow kontra thiserror oraz własne typy błędów. - 90golang-error-handling
Podpowiada idiomatyczną obsługę błędów w Go: opakowywanie przez %w, errors.Is i As, logowanie przez slog i middleware HTTP. - 100handling-rust-errors
Opisuje wzorce obsługi błędów HASH z użyciem crate error-stack w Rust: typy Result i Report, własne błędy, change_context, attach, trait Error i dokumentowanie warunków błędów.