0
0
GoHow-ToBeginner · 3 min read

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 true if err matches target directly 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 if err matches target or wraps it.
  • Wrap errors with %w in fmt.Errorf to enable errors.Is to 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.