Home > Backend Development > Golang > How Can I Achieve True Recursive Error Wrapping and Unwrapping in Go?

How Can I Achieve True Recursive Error Wrapping and Unwrapping in Go?

Susan Sarandon
Release: 2024-12-12 14:52:10
Original
571 people have browsed it

How Can I Achieve True Recursive Error Wrapping and Unwrapping in Go?

Error Wrapping with Recursive Is() and As() in Go

Many developers recommend wrapping errors in Go using fmt.Errorf with the %w verb, but this method does not provide true recursive wrapping. To recursively check errors using Is() and As(), custom error types can be used.

Custom Error Types for Recursion

Here's a custom error type errorChain that supports error wrapping and recursive checks:

type errorChain struct {
    err  error
    next *errorChain
}

func Wrap(errs ...error) error {
    out := errorChain{err: errs[0]}

    n := &out
    for _, err := range errs[1:] {
        n.next = &errorChain{err: err}
        n = n.next
    }
    return out
}
Copy after login

Adding Is() and As() to the Custom Type

The key to enabling recursive checks is to implement both Is() and As() methods on the custom type. These methods allow error comparisons at the error contained within the chain, rather than the chain itself:

func (c errorChain) Is(err error) bool { return errors.Is(c.err, err) }

func (c errorChain) As(target any) bool { return errors.As(c.err, target) }
Copy after login

Using errorChain

With these methods in place, you can wrap errors and perform recursive checks:

errs := Wrap(errors.New("error 0"), errors.New("error 1"), errors.New("error 2"))

fmt.Println(errors.Is(errs, errors.New("error 0")))  // true
fmt.Println(errors.Is(errs, errors.New("error 1")))  // true
fmt.Println(errors.Is(errs, errors.New("error 2")))  // true
Copy after login

Using Unwrap() to Iterate the Chain

The Unwrap() method in errorChain allows you to traverse the wrapped errors in a chain:

var currentError error = errs
for {
    currentError = errors.Unwrap(currentError)
    if currentError == nil {
        break
    }
    fmt.Println(currentError)
}
Copy after login

This example prints all the errors in the chain:

error 0
error 1
error 2
Copy after login

The above is the detailed content of How Can I Achieve True Recursive Error Wrapping and Unwrapping in Go?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Latest Articles by Author
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template