How to Use errors.Is in Go for Error Comparison
In Go, use
errors.Is(err, target) to check if an error err is or wraps a specific target error. It returns true if err matches target directly or through wrapping, making error comparison reliable.Syntax
The errors.Is function takes two parameters: the error to check (err) and the target error (target) you want to compare against. It returns a boolean indicating if err is or wraps target.
err: The error you received.target: The error you want to check for.- Returns
trueiferrmatchestargetdirectly or through wrapping.
go
errors.Is(err, target) bool
Example
This example shows how to create a custom error, wrap it with additional context, and then use errors.Is to check if the wrapped error matches the original error.
go
package main import ( "errors" "fmt" ) var ErrNotFound = errors.New("item not found") func findItem(id int) error { // Simulate an error return fmt.Errorf("failed to find item %d: %w", id, ErrNotFound) } func main() { err := findItem(42) if errors.Is(err, ErrNotFound) { fmt.Println("The error is ErrNotFound") } else { fmt.Println("Different error") } }
Output
The error is ErrNotFound
Common Pitfalls
One common mistake is comparing errors using == instead of errors.Is. This fails when errors are wrapped because == only checks exact equality, not wrapped errors.
Another pitfall is not wrapping errors with %w in fmt.Errorf, which is necessary for errors.Is to work properly.
go
package main import ( "errors" "fmt" ) var ErrNotFound = errors.New("item not found") func findItemWrong(id int) error { // Wrapping error incorrectly (using %v instead of %w) return fmt.Errorf("failed to find item %d: %v", id, ErrNotFound) } func main() { err := findItemWrong(42) // This will print "Different error" because errors.Is won't detect wrapped error if errors.Is(err, ErrNotFound) { fmt.Println("The error is ErrNotFound") } else { fmt.Println("Different error") } }
Output
Different error
Quick Reference
- Use
errors.Is(err, target)to check iferrmatchestargetor wraps it. - Wrap errors with
%winfmt.Errorfto enableerrors.Isto work. - Do not use
==to compare errors when wrapping is involved.
Key Takeaways
Use errors.Is to check if an error matches or wraps a target error safely.
Always wrap errors with %w in fmt.Errorf to preserve error chains.
Avoid using == to compare errors when wrapping is possible.
errors.Is returns true if the error or any wrapped error matches the target.