Good Code
The good version adds operation context and preserves an inspectable error chain for callers that use errors.Is.
Lesson 03
Return errors with useful context and wrap underlying errors when callers should be able to inspect them.
var ErrReviewNotFound = errors.New("review not found")
func (r *Repository) Find(ctx context.Context, id string) (Review, error) {
review, err := r.store.FindReview(ctx, id)
if errors.Is(err, store.ErrNotFound) {
return Review{}, fmt.Errorf("find review %s: %w", id, ErrReviewNotFound)
}
if err != nil {
return Review{}, fmt.Errorf("find review %s: %w", id, err)
}
return review, nil
}func (r *Repository) Find(ctx context.Context, id string) (Review, error) {
review, err := r.store.FindReview(ctx, id)
if err != nil {
log.Println("find review failed", err)
return Review{}, errors.New("failed")
}
return review, nil
}The good version adds operation context and preserves an inspectable error chain for callers that use errors.Is.
The bad version logs and replaces the original error with a vague message. Callers lose the reason and cannot make a precise decision.