patterngoModeratepending
Go error handling patterns and best practices
Viewed 0 times
error handlingerrors.Iserrors.Aserror wrappingsentinel errorcustom error
Problem
Need idiomatic Go error handling: wrapping, custom errors, sentinel errors, and error type checking.
Solution
Go error handling patterns:
import (
"errors"
"fmt"
)
// 1. Sentinel errors (predefined error values)
var (
ErrNotFound = errors.New("not found")
ErrUnauthorized = errors.New("unauthorized")
ErrValidation = errors.New("validation failed")
)
// Check with errors.Is
if errors.Is(err, ErrNotFound) {
http.Error(w, "Not found", 404)
}
// 2. Custom error types (carry context)
type ValidationError struct {
Field string
Message string
}
func (e *ValidationError) Error() string {
return fmt.Sprintf("%s: %s", e.Field, e.Message)
}
// Check with errors.As
var ve *ValidationError
if errors.As(err, &ve) {
fmt.Printf("Field %s: %s\n", ve.Field, ve.Message)
}
// 3. Wrapping errors (add context while preserving original)
func getUser(id string) (*User, error) {
row := db.QueryRow("SELECT ...")
if err := row.Scan(&user); err != nil {
return nil, fmt.Errorf("getUser(%s): %w", id, err)
// %w wraps the error (errors.Is/As can unwrap it)
}
return &user, nil
}
// 4. Don't just check errors, handle them
// BAD: Log and return (double handling)
if err != nil {
log.Printf("error: %v", err) // Logged here
return err // AND handled by caller
}
// GOOD: Handle at one level only
if err != nil {
return fmt.Errorf("processing order: %w", err) // Add context, let caller decide
}
// 5. Errors are values - use them creatively
type errWriter struct {
w io.Writer
err error
}
func (ew *errWriter) write(data []byte) {
if ew.err != nil {
return // Skip if already errored
}
_, ew.err = ew.w.Write(data)
}
// Usage: check error once at the end
ew := &errWriter{w: file}
ew.write(header)
ew.write(body)
ew.write(footer)
if ew.err != nil {
return ew.err
}Why
Go treats errors as values, not exceptions. The explicit if err != nil pattern forces handling at each level, with wrapping providing the context trail for debugging.
Context
Go application error handling
Revisions (0)
No revisions yet.