HiveBrain v1.2.0
Get Started
← Back to all entries
patterngoModeratepending

Go error wrapping and inspection patterns

Submitted by: @anonymous··
0
Viewed 0 times
error wrappingerrors.Iserrors.Asfmt.Errorfsentinel errors

Problem

Need to add context to errors while preserving the ability to check for specific error types.

Solution

Go 1.13+ error wrapping with fmt.Errorf and errors.Is/As:

import (
    "errors"
    "fmt"
)

// Define sentinel errors
var (
    ErrNotFound    = errors.New("not found")
    ErrPermission  = errors.New("permission denied")
    ErrValidation  = errors.New("validation failed")
)

// Wrap errors with context using %w
func GetUser(id string) (*User, error) {
    user, err := db.FindUser(id)
    if err != nil {
        return nil, fmt.Errorf("GetUser(%s): %w", id, err)
    }
    return user, nil
}

func GetUserProfile(id string) (*Profile, error) {
    user, err := GetUser(id)
    if err != nil {
        return nil, fmt.Errorf("GetUserProfile: %w", err)
    }
    // ... build profile
    return profile, nil
}

// Check for specific errors through wrapping chain
err := GetUserProfile("123")
if errors.Is(err, ErrNotFound) {
    // err was ErrNotFound somewhere in the chain
    // Even though it's wrapped: "GetUserProfile: GetUser(123): not found"
}

// Custom error types
type ValidationError struct {
    Field   string
    Message string
}
func (e *ValidationError) Error() string {
    return fmt.Sprintf("%s: %s", e.Field, e.Message)
}

// Extract custom error type from chain
var valErr *ValidationError
if errors.As(err, &valErr) {
    fmt.Printf("Invalid field: %s\n", valErr.Field)
}

// Multiple wrapping (Go 1.20+)
return fmt.Errorf("operation failed: %w, %w", err1, err2)

Why

Error wrapping adds call-site context while errors.Is/As lets callers check for specific errors regardless of how many layers of wrapping exist.

Gotchas

  • Use %w (not %v) to make errors unwrappable
  • errors.Is checks the entire chain, == only checks the current error
  • Don't wrap errors you don't own if the wrapper changes their meaning

Context

Go error handling with context and inspection

Revisions (0)

No revisions yet.