errorwrap
About 355 wordsAbout 1 min
2025-01-16
Detects bare error returns that lose context.
Category
Error Handling
What It Checks
This analyzer finds error returns that don't add context, making debugging difficult.
Why It Matters
Bare error returns lose the call chain:
Error: connection refusedWith context, you can trace the error:
Error: get user "alice": fetch from database: connection refusedExamples
Bad
func ProcessOrder(orderID string) error {
order, err := db.GetOrder(orderID)
if err != nil {
return err // Lost context: what were we doing?
}
if err := validateOrder(order); err != nil {
return err // Lost context: which order failed?
}
return nil
}Good: Using humane.Wrap (Recommended)
func ProcessOrder(orderID string) humane.Error {
order, err := db.GetOrder(orderID)
if err != nil {
return humane.Wrap(err, "failed to get order",
"verify order ID exists in the database",
"check database connectivity")
}
if err := validateOrder(order); err != nil {
return humane.Wrap(err, "order validation failed",
"review the order details for required fields")
}
return nil
}Good: Using fmt.Errorf
func ProcessOrder(orderID string) error {
order, err := db.GetOrder(orderID)
if err != nil {
return fmt.Errorf("get order %s: %w", orderID, err)
}
if err := validateOrder(order); err != nil {
return fmt.Errorf("validate order %s: %w", orderID, err)
}
return nil
}Prefer humane.Wrap()
When possible, use humane.Wrap() instead of fmt.Errorf():
- Provides actionable advice to users
- Creates structured error messages
- Enables better error presentation in CLIs
The %w Verb
If using fmt.Errorf, use %w (not %v or %s) to wrap errors:
// Good: preserves error chain for errors.Is/As
return fmt.Errorf("context: %w", err)
// Bad: breaks error chain
return fmt.Errorf("context: %v", err)Exceptions
The analyzer allows bare returns in certain cases:
// Allowed: returning sentinel errors
if notFound {
return ErrNotFound // Sentinel error, context not needed
}
// Allowed: simple getters that add no context
func (s *Service) Client() *http.Client {
return s.client
}Configuration
# .golint-sl.yaml
analyzers:
errorwrap: true # enabled by defaultWhen to Disable
- Very simple functions where context is obvious
- Performance-critical paths (wrapping has overhead)
analyzers:
errorwrap: falseRelated Analyzers
- humaneerror - User-facing errors
- sentinelerrors - Sentinel error patterns
