A function may return an error with useful context wrapped around a recognizable error. Comparing only the returned error with a sentinel can miss that sentinel. Use errors.Is(err, target) to ask whether the target matches anywhere in err’s error chain. section 5.1.3
Check a validation error
A word-game validator returns fmt.Errorf("expected %d, got %d, %w", expected, actual, errInvalidWordLength) when a guess has the wrong length. A table-driven test checks errors.Is(err, tc.expected): the valid-guess case expects nil, while the too-long case expects errInvalidWordLength. The test recognizes the sentinel without depending on the added length details. section 5.1.3
Listing 5.16 game_internal_test.go: Testing the validateGuess method
package gordle
import (
"errors"
"testing"
)
func TestGameValidateGuess(t *testing.T) {
tt := map[string]struct { #1
word []rune
expected error
}{
"nominal": { #2
word: []rune("GUESS"),
expected: nil,
},
"too long": {
word: []rune("POCKET"),
expected: errInvalidWordLength,
}
}
for name, tc := range tt {
t.Run(name, func(t *testing.T) {
g := New(nil) #3
err := g.validateGuess(tc.word) #4
if !errors.Is(err, tc.expected) { #5
t.Errorf("%c, expected %q, got %q",
tc.word, tc.expected, err) #6
}
})
}
}
The test places expected errors beside inputs and uses errors.Is for both the nil success case and a wrapped validation error. section 5.1.3
Keep the error a caller needs to recognize in the returned chain:
- Wrap a package sentinel with %w when adding context. ParseDecimal does this for ErrInvalidDecimal when integer parsing fails; its tests also check errors such as ErrTooLarge. section 6.2.4
- At an HTTP boundary, expose a package-specific sentinel rather than requiring callers to recognize net/http errors. Callers can then check its meaning with errors.Is. section 6.5.3
Use errors.As when the decision requires extracting a particular error type. For example, a gRPC endpoint uses errors.As to recognize InvalidInputError and return InvalidArgument; other errors become Internal. errors.Is is the simpler check when the question is whether a target error matches. section 10.3.2


