...

Source file src/github.com/go-errors/errors/error_backward.go

Documentation: github.com/go-errors/errors

     1  //go:build !go1.13
     2  // +build !go1.13
     3  
     4  package errors
     5  
     6  import (
     7  	"reflect"
     8  )
     9  
    10  type unwrapper interface {
    11  	Unwrap() error
    12  }
    13  
    14  // As assigns error or any wrapped error to the value target points
    15  // to. If there is no value of the target type of target As returns
    16  // false.
    17  func As(err error, target interface{}) bool {
    18  	targetType := reflect.TypeOf(target)
    19  
    20  	for {
    21  		errType := reflect.TypeOf(err)
    22  
    23  		if errType == nil {
    24  			return false
    25  		}
    26  
    27  		if reflect.PtrTo(errType) == targetType {
    28  			reflect.ValueOf(target).Elem().Set(reflect.ValueOf(err))
    29  			return true
    30  		}
    31  
    32  		wrapped, ok := err.(unwrapper)
    33  		if ok {
    34  			err = wrapped.Unwrap()
    35  		} else {
    36  			return false
    37  		}
    38  	}
    39  }
    40  
    41  // Is detects whether the error is equal to a given error. Errors
    42  // are considered equal by this function if they are the same object,
    43  // or if they both contain the same error inside an errors.Error.
    44  func Is(e error, original error) bool {
    45  	if e == original {
    46  		return true
    47  	}
    48  
    49  	if e, ok := e.(*Error); ok {
    50  		return Is(e.Err, original)
    51  	}
    52  
    53  	if original, ok := original.(*Error); ok {
    54  		return Is(e, original.Err)
    55  	}
    56  
    57  	return false
    58  }
    59  
    60  // Disclaimer: functions Join and Unwrap are copied from the stdlib errors
    61  // package v1.21.0.
    62  
    63  // Join returns an error that wraps the given errors.
    64  // Any nil error values are discarded.
    65  // Join returns nil if every value in errs is nil.
    66  // The error formats as the concatenation of the strings obtained
    67  // by calling the Error method of each element of errs, with a newline
    68  // between each string.
    69  //
    70  // A non-nil error returned by Join implements the Unwrap() []error method.
    71  func Join(errs ...error) error {
    72  	n := 0
    73  	for _, err := range errs {
    74  		if err != nil {
    75  			n++
    76  		}
    77  	}
    78  	if n == 0 {
    79  		return nil
    80  	}
    81  	e := &joinError{
    82  		errs: make([]error, 0, n),
    83  	}
    84  	for _, err := range errs {
    85  		if err != nil {
    86  			e.errs = append(e.errs, err)
    87  		}
    88  	}
    89  	return e
    90  }
    91  
    92  type joinError struct {
    93  	errs []error
    94  }
    95  
    96  func (e *joinError) Error() string {
    97  	var b []byte
    98  	for i, err := range e.errs {
    99  		if i > 0 {
   100  			b = append(b, '\n')
   101  		}
   102  		b = append(b, err.Error()...)
   103  	}
   104  	return string(b)
   105  }
   106  
   107  func (e *joinError) Unwrap() []error {
   108  	return e.errs
   109  }
   110  
   111  // Unwrap returns the result of calling the Unwrap method on err, if err's
   112  // type contains an Unwrap method returning error.
   113  // Otherwise, Unwrap returns nil.
   114  //
   115  // Unwrap only calls a method of the form "Unwrap() error".
   116  // In particular Unwrap does not unwrap errors returned by [Join].
   117  func Unwrap(err error) error {
   118  	u, ok := err.(interface {
   119  		Unwrap() error
   120  	})
   121  	if !ok {
   122  		return nil
   123  	}
   124  	return u.Unwrap()
   125  }
   126  

View as plain text