Skip to content

Commit

Permalink
add functions Join and Unwrap
Browse files Browse the repository at this point in the history
  • Loading branch information
lovromazgon committed Aug 30, 2023
1 parent 1334694 commit bad9aac
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 2 deletions.
34 changes: 32 additions & 2 deletions error_1_13.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build go1.13
// +build go1.13

package errors
Expand All @@ -6,14 +7,17 @@ import (
baseErrors "errors"
)

// find error in any wrapped error
// As finds the first error in err's tree that matches target, and if one is found, sets
// target to that error value and returns true. Otherwise, it returns false.
//
// For more information see stdlib errors.As.
func As(err error, target interface{}) bool {
return baseErrors.As(err, target)
}

// Is detects whether the error is equal to a given error. Errors
// are considered equal by this function if they are matched by errors.Is
// or if their contained errors are matched through errors.Is
// or if their contained errors are matched through errors.Is.
func Is(e error, original error) bool {
if baseErrors.Is(e, original) {
return true
Expand All @@ -29,3 +33,29 @@ func Is(e error, original error) bool {

return false
}

// Join returns an error that wraps the given errors.
// Any nil error values are discarded.
// Join returns nil if every value in errs is nil.
// The error formats as the concatenation of the strings obtained
// by calling the Error method of each element of errs, with a newline
// between each string.
//
// A non-nil error returned by Join implements the Unwrap() []error method.
//
// For more information see stdlib errors.Join.
func Join(errs ...error) error {
return baseErrors.Join(errs...)
}

// Unwrap returns the result of calling the Unwrap method on err, if err's
// type contains an Unwrap method returning error.
// Otherwise, Unwrap returns nil.
//
// Unwrap only calls a method of the form "Unwrap() error".
// In particular Unwrap does not unwrap errors returned by [Join].
//
// For more information see stdlib errors.Unwrap.
func Unwrap(err error) error {
return baseErrors.Unwrap(err)
}
68 changes: 68 additions & 0 deletions error_backward.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build !go1.13
// +build !go1.13

package errors
Expand Down Expand Up @@ -55,3 +56,70 @@ func Is(e error, original error) bool {

return false
}

// Disclaimer: functions Join and Unwrap are copied from the stdlib errors
// package v1.21.0.

// Join returns an error that wraps the given errors.
// Any nil error values are discarded.
// Join returns nil if every value in errs is nil.
// The error formats as the concatenation of the strings obtained
// by calling the Error method of each element of errs, with a newline
// between each string.
//
// A non-nil error returned by Join implements the Unwrap() []error method.
func Join(errs ...error) error {
n := 0
for _, err := range errs {
if err != nil {
n++
}
}
if n == 0 {
return nil
}
e := &joinError{
errs: make([]error, 0, n),
}
for _, err := range errs {
if err != nil {
e.errs = append(e.errs, err)
}
}
return e
}

type joinError struct {
errs []error
}

func (e *joinError) Error() string {
var b []byte
for i, err := range e.errs {
if i > 0 {
b = append(b, '\n')
}
b = append(b, err.Error()...)
}
return string(b)
}

func (e *joinError) Unwrap() []error {
return e.errs
}

// Unwrap returns the result of calling the Unwrap method on err, if err's
// type contains an Unwrap method returning error.
// Otherwise, Unwrap returns nil.
//
// Unwrap only calls a method of the form "Unwrap() error".
// In particular Unwrap does not unwrap errors returned by [Join].
func Unwrap(err error) error {
u, ok := err.(interface {
Unwrap() error
})
if !ok {
return nil
}
return u.Unwrap()
}

0 comments on commit bad9aac

Please sign in to comment.