Implement Go error handling patterns including error wrapping, sentinel errors, custom error types, and error handling conventions. Use when handling errors, creating error types, or implementing error propagation. Trigger words include "error", "panic", "recover", "error handling", "error wrapping".
View on GitHubarmanzeroeight/fastagent-plugins
go-toolkit
January 21, 2026
Select agents to install to:
npx add-skill https://github.com/armanzeroeight/fastagent-plugins/blob/main/plugins/go-toolkit/skills/error-handling/SKILL.md -a claude-code --skill error-handlingInstallation paths:
.claude/skills/error-handling/# Error Handling
Implement idiomatic Go error handling patterns.
## Quick Start
**Basic error handling:**
```go
result, err := doSomething()
if err != nil {
return fmt.Errorf("do something: %w", err)
}
```
**Sentinel error:**
```go
var ErrNotFound = errors.New("not found")
if errors.Is(err, ErrNotFound) {
// Handle not found
}
```
## Instructions
### Step 1: Return Errors
**Basic error return:**
```go
func ReadFile(path string) ([]byte, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("read file %s: %w", path, err)
}
return data, nil
}
```
**Multiple return values:**
```go
func Divide(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("division by zero")
}
return a / b, nil
}
```
### Step 2: Wrap Errors with Context
**Using fmt.Errorf with %w:**
```go
func ProcessFile(path string) error {
data, err := ReadFile(path)
if err != nil {
return fmt.Errorf("process file: %w", err)
}
if err := Validate(data); err != nil {
return fmt.Errorf("validate data: %w", err)
}
return nil
}
```
**Error chain:**
```go
// Original error
err := os.Open("file.txt")
// Wrapped once
err = fmt.Errorf("open config: %w", err)
// Wrapped again
err = fmt.Errorf("initialize app: %w", err)
// Unwrap to check original
if errors.Is(err, os.ErrNotExist) {
// Handle file not found
}
```
### Step 3: Use Sentinel Errors
**Define sentinel errors:**
```go
var (
ErrNotFound = errors.New("not found")
ErrUnauthorized = errors.New("unauthorized")
ErrInvalidInput = errors.New("invalid input")
)
func GetUser(id string) (*User, error) {
user, ok := cache[id]
if !ok {
return nil, ErrNotFound
}
return user, nil
}
```
**Check with errors.Is:**
```go
user, err := GetUser("123")
if errors.Is(err, ErrNotFound) {
// Handle not found case
return nil
}
if err != nil {
// Handle other errors
return e