Golang errors.Is Function

The errors.Is function in Go is used to determine whether a specific error is present in a chain of wrapped errors. This function is part of the errors package and is particularly useful when you need to check if an error is equivalent to a specific target error, even if the error has been wrapped with additional context.

Syntax

func Is(err, target error) bool

Parameters:

  • err: The error to be checked. This can be a simple error or an error that has been wrapped with additional context.
  • target: The specific error you want to check for in the error chain.

Returns:

  • bool: Returns true if the target error is found in the error chain; otherwise, it returns false.

Example Usage

Basic Example

This example demonstrates how to use errors.Is to check if a given error is equivalent to a target error.

package main

import (
	"errors"
	"fmt"
)

var ErrNotFound = errors.New("item not found")

func findItem(id int) error {
	// Simulate an item not found situation
	return ErrNotFound
}

func main() {
	err := findItem(1)

	if errors.Is(err, ErrNotFound) {
		fmt.Println("Error: the item was not found.")
	} else {
		fmt.Println("Error: an unknown error occurred.")
	}
}

Output:

Error: the item was not found.

Using errors.Is with Wrapped Errors

The errors.Is function is particularly useful when dealing with wrapped errors, where an error is wrapped with additional context using fmt.Errorf or similar functions.

Example

package main

import (
	"errors"
	"fmt"
)

var ErrPermission = errors.New("permission denied")

func openFile(filename string) error {
	// Simulate a permission error wrapped with additional context
	return fmt.Errorf("cannot open file %s: %w", filename, ErrPermission)
}

func main() {
	err := openFile("data.txt")

	if errors.Is(err, ErrPermission) {
		fmt.Println("Error: permission denied.")
	} else {
		fmt.Println("Error: an unknown error occurred.")
	}
}

Output:

Error: permission denied.

Explanation:

  • The openFile function simulates a permission error, wrapping it with additional context using fmt.Errorf and the %w verb.
  • The errors.Is function checks if the original ErrPermission is part of the error chain.

Combining errors.Is with Custom Error Types

You can also use errors.Is to check for custom error types by defining them as variables.

Example

package main

import (
	"errors"
	"fmt"
)

type ValidationError struct {
	Message string
}

func (e *ValidationError) Error() string {
	return e.Message
}

var ErrInvalidInput = &ValidationError{"invalid input"}

func validate(input string) error {
	if input == "" {
		return fmt.Errorf("validation failed: %w", ErrInvalidInput)
	}
	return nil
}

func main() {
	err := validate("")

	if errors.Is(err, ErrInvalidInput) {
		fmt.Println("Error: invalid input provided.")
	} else {
		fmt.Println("Error: an unknown error occurred.")
	}
}

Output:

Error: invalid input provided.

Explanation:

  • The ValidationError type is defined with an error message.
  • The validate function checks for invalid input and wraps the custom error ErrInvalidInput.
  • The errors.Is function successfully identifies the wrapped custom error.

Conclusion

The errors.Is function in Go is used for error handling, particularly when working with wrapped errors. It allows you to check if a specific error is present in the chain of errors, making it easier to handle and respond to errors in your applications. By using errors.Is, you can create more robust and maintainable error-handling logic, especially in complex systems where errors might be wrapped with additional context.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top