Go

Explain errors.As. Why must the target be a pointer, and what happens if you get it wrong?

Question 298HardGo 1.22 to 1.25

errors.As(err, target any) bool finds the first error in the tree that is assignable to the type *target points at, stores it in *target, and returns true. A node can also match through an As(any) bool method. The target must be a non-nil pointer to either a type that implements error or any interface type. Otherwise As panics. go vet's errorsas check catches most of these mistakes.

_, err := os.Open("/nope")

var pe *fs.PathError
if errors.As(err, &pe) { // note: **fs.PathError
	fmt.Println(pe.Op, pe.Path) // open /nope
}

// errors.As(err, pe)            // panic: target must be a non-nil pointer
// var x fs.PathError
// errors.As(err, &x)            // panic: *target must be interface or implement error
//                                // (Error has a pointer receiver, so fs.PathError doesn't implement error)

var t interface{ Timeout() bool } // interface targets are allowed
_ = errors.As(err, &t)

Go 1.26 adds the generic errors.AsType[E error](err) (E, bool), which checks types at compile time: if pe, ok := errors.AsType[*fs.PathError](err); ok { ... }. Interviewer focus: you must know whether the error type uses a pointer or value receiver, because that decides the target type.

More on Error Handling & panics

All 37 Error Handling & panics questions