SKILL.md
$27
- Returned errors MUST always be checked — NEVER discard with
_
- Errors MUST be wrapped with context using
fmt.Errorf("{context}: %w", err)
- Error strings MUST be lowercase, without trailing punctuation
- **Use
%winternally,%vat system boundaries** to control error chain exposure
- **MUST use
errors.Isanderrors.As** instead of direct comparison or type assertion
- **SHOULD use
errors.Join** (Go 1.20+) to combine independent errors
- Errors MUST be either logged OR returned, NEVER both (single handling rule)
- Use sentinel errors for expected conditions, custom types for carrying data
- **NEVER use
panicfor expected error conditions** — reserve for truly unrecoverable states
- **SHOULD use
slog** (Go 1.21+) for structured error logging — notfmt.Printlnorlog.Printf
- **Use
samber/oops** for production errors needing stack traces, user/tenant context, or structured attributes
- Log HTTP requests with structured middleware capturing method, path, status, and duration
- Use log levels to indicate error severity
- Never expose technical errors to users — translate internal errors to user-friendly messages, log technical details separately
- Keep error messages low-cardinality — don't interpolate variable data (IDs, paths, line numbers) into error strings; attach them as structured attributes instead (via
slogat the log site, or viasamber/oops.With()on the error itself) so APM/log aggregators (Datadog, Loki, Sentry) can group errors properly
Detailed Reference
-
Error Creation — How to create errors that tell the story: error messages should be lowercase, no punctuation, and describe what happened without prescribing action. Covers sentinel errors (one-time preallocation for performance), custom error types (for carrying rich context), and the decision table for which to use when.
-
Error Wrapping and Inspection — Why fmt.Errorf("{context}: %w", err) beats fmt.Errorf("{context}: %v", err) (chains vs concatenation). How to inspect chains with errors.Is/errors.As for type-safe error handling, and errors.Join for combining independent errors.
-
Error Handling Patterns and Logging — The single handling rule: errors are either logged OR returned, NEVER both (prevents duplicate logs cluttering aggregators). Panic/recover design, samber/oops for production errors, and slog structured logging integration for APM tools.
Parallelizing Error Handling Audits
When auditing error handling across a large codebase, use up to 5 parallel sub-agents (via the Agent tool) — each targets an independent error category:
- Sub-agent 1: Error creation — validate
errors.New/fmt.Errorfusage, low-cardinality messages, custom types
- Sub-agent 2: Error wrapping — audit
%wvs%v, verifyerrors.Is/errors.Aspatterns
- Sub-agent 3: Single handling rule — find log-and-return violations, swallowed errors, discarded errors (
_)
- Sub-agent 4: Panic/recover — audit
panicusage, verify recovery at goroutine boundaries
- Sub-agent 5: Structured logging — verify
slogusage at error sites, check for PII in error messages
Cross-References
- → See
samber/cc-skills-golang@golang-samber-oopsfor full samber/oops API, builder patterns, and logger integration
- → See
samber/cc-skills-golang@golang-observabilityfor structured logging setup, log levels, and request logging middleware
- → See
samber/cc-skills-golang@golang-safetyfor nil interface trap and nil error comparison pitfalls
- → See
samber/cc-skills-golang@golang-namingfor error naming conventions (ErrNotFound, PathError)
- → See
samber/cc-skills-golang@golang-continuous-integrationskill for automated AI-driven code review in CI using these guidelines