0
0
GoHow-ToBeginner · 3 min read

How to Use errors.As in Go for Error Type Checking

In Go, use errors.As to check if an error or any error it wraps matches a specific type and to extract that error. It takes the original error and a pointer to a target variable, returning true if the target type is found anywhere in the error chain.
📐

Syntax

The errors.As function has this syntax:

  • errors.As(err error, target interface{}) bool

Here, err is the error you want to check, and target is a pointer to a variable of the error type you want to find. If err or any wrapped error matches the target type, errors.As sets the target to that error and returns true.

go
package main

import (
	"errors"
	"fmt"
)

func main() {
	var target *MyError
	err := someFunc()
	if errors.As(err, &target) {
		fmt.Println("Found MyError:", target.Message)
	} else {
		fmt.Println("MyError not found")
	}
}

type MyError struct {
	Message string
}

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

func someFunc() error {
	return &MyError{"something went wrong"}
}
💻

Example

This example shows how to use errors.As to detect and extract a custom error type from a wrapped error.

go
package main

import (
	"errors"
	"fmt"
)

type MyError struct {
	Message string
}

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

func someFunc() error {
	// Wrap MyError inside another error
	return fmt.Errorf("wrapper: %w", &MyError{"something went wrong"})
}

func main() {
	var target *MyError
	err := someFunc()
	if errors.As(err, &target) {
		fmt.Println("Found MyError:", target.Message)
	} else {
		fmt.Println("MyError not found")
	}
}
Output
Found MyError: something went wrong
⚠️

Common Pitfalls

Common mistakes when using errors.As include:

  • Passing the target variable directly instead of a pointer to it (use &target).
  • Using errors.Is when you need to extract the error type instead of just checking equality.
  • Not handling wrapped errors properly, missing the chance to detect nested errors.

Always pass a pointer to the target variable so errors.As can assign the matched error.

go
package main

import (
	"errors"
	"fmt"
)

type MyError struct {
	Message string
}

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

func someFunc() error {
	return &MyError{"error occurred"}
}

func main() {
	var target *MyError
	err := someFunc()

	// Wrong: passing target instead of &target
	if errors.As(err, target) {
		fmt.Println("Found MyError:", target.Message)
	} else {
		fmt.Println("MyError not found")
	}

	// Correct:
	if errors.As(err, &target) {
		fmt.Println("Found MyError correctly:", target.Message)
	}
}
Output
MyError not found Found MyError correctly: error occurred
📊

Quick Reference

Remember these key points when using errors.As:

  • Use it to check and extract specific error types from wrapped errors.
  • Always pass a pointer to the target variable.
  • Returns true if the error or any wrapped error matches the target type.
  • Useful for handling custom error types in complex error chains.

Key Takeaways

Use errors.As to find and extract specific error types from wrapped errors.
Always pass a pointer to the target variable to errors.As.
errors.As returns true if the error or any wrapped error matches the target type.
It helps handle custom error types safely in error chains.
Avoid confusing errors.As with errors.Is; use As to extract, Is to check equality.