cxuu/golang-skills
Overview
This skill codifies idiomatic Go error handling distilled from Google and Uber style guidance. It explains when to return errors, how to wrap and classify them, and how to structure error flow for clear, maintainable code. Use it to make consistent, production-ready decisions about creating, returning, inspecting, and logging errors.
How this skill works
The skill inspects common error-handling scenarios and recommends concrete patterns: always return the error interface, prefer zero values for other returns, and indent error handling before normal flow. It recommends when to wrap with %w to preserve error chains, when to use %v for boundaries, and when to define sentinel or custom error types for programmatic checks. It also enforces the principle of handling an error exactly once (return, log & degrade, or match & handle).
When to use it
- Writing functions that can fail or return nil/zero values
- Deciding whether to wrap errors or expose internals at system boundaries
- Choosing sentinel errors, errors.New, or custom error types for callers
- Structuring control flow to keep the normal path unindented and readable
- Implementing logging policies to avoid duplicate logs across call stacks
Best practices
- Always return the error interface (error) from exported functions; avoid concrete error types
- Keep error strings lowercase and without trailing punctuation unless part of a displayed message
- Handle errors immediately and unindent the normal path; avoid else blocks that hide normal flow
- Use %w at the end of fmt.Errorf("context: %w", err) when callers must inspect the chain; use %v at boundaries to hide internals
- Choose one response to an error: return (possibly wrapped), log and degrade, or match and handle — do not log then return
- When ignoring an error intentionally, document why with a clear comment
Example use cases
- API handler that wraps storage errors with context using %w so middleware can inspect causes
- Library function that returns sentinel errors (var ErrNotFound) for callers to check with errors.Is
- Background task that logs metric failures and continues without returning the error to avoid duplicate handling
- Code refactor to move error checks to the top of a function so the happy path is easy to read
- Choosing a custom error type when callers need to extract structured fields from the error for programmatic branching
FAQ
Always prefer errors.Is or errors.As to inspect wrapped errors. Avoid string matching because messages can change and are not reliable for programmatic checks.
Should exported functions ever return concrete error types?
No. Exported functions should return the error interface to avoid subtle nil/interface mishaps and to keep callers free to inspect via errors.Is/As.
2 skills
This skill guides idiomatic Go error handling by applying wrapping, sentinel, and flow patterns for robust, maintainable code.
This skill helps you optimize Go code by applying performance patterns for efficient string handling, conversions, and container capacity.