github.com/yaling888/clash@v1.53.0/common/errors2/err.go (about)

     1  package errors2
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  )
     7  
     8  func New(err error) error {
     9  	return NewSplit(", ", err)
    10  }
    11  
    12  func Cause(err error) error {
    13  	return NewSplit(", cause: ", err)
    14  }
    15  
    16  func Join(errs ...error) error {
    17  	return JoinSplit(", ", errs...)
    18  }
    19  
    20  func NewSplit(split string, err error) error {
    21  	if err == nil {
    22  		return nil
    23  	}
    24  
    25  	if reflect.TypeOf(err) == wrapErrorsType {
    26  		return err
    27  	}
    28  
    29  	if x, ok := err.(interface{ Unwrap() []error }); ok {
    30  		if x == nil {
    31  			return err
    32  		}
    33  		u := x.Unwrap()
    34  		e := &joinError{
    35  			split: split,
    36  			errs:  make([]error, 0, len(u)<<2),
    37  		}
    38  		for _, m := range u {
    39  			if m == nil {
    40  				continue
    41  			}
    42  			if reflect.TypeOf(m) == wrapErrorsType {
    43  				e.errs = append(e.errs, m)
    44  				continue
    45  			}
    46  			n := NewSplit(split, m)
    47  			if n == nil {
    48  				continue
    49  			}
    50  			if y, ok1 := n.(interface{ Unwrap() []error }); ok1 {
    51  				if y == nil {
    52  					e.errs = append(e.errs, n)
    53  					continue
    54  				}
    55  				v := y.Unwrap()
    56  				for _, z := range v {
    57  					if z == nil {
    58  						continue
    59  					}
    60  					e.errs = append(e.errs, z)
    61  				}
    62  				continue
    63  			}
    64  			e.errs = append(e.errs, n)
    65  		}
    66  		return e
    67  	}
    68  
    69  	return err
    70  }
    71  
    72  func JoinSplit(split string, errs ...error) error {
    73  	n := 0
    74  	for _, err := range errs {
    75  		if err != nil {
    76  			n++
    77  		}
    78  	}
    79  	if n == 0 {
    80  		return nil
    81  	}
    82  	e := &joinError{
    83  		errs:  make([]error, 0, n),
    84  		split: split,
    85  	}
    86  	for _, err := range errs {
    87  		if err != nil {
    88  			e.errs = append(e.errs, err)
    89  		}
    90  	}
    91  	return e
    92  }
    93  
    94  type joinError struct {
    95  	errs  []error
    96  	split string
    97  }
    98  
    99  func (e *joinError) Error() string {
   100  	var b []byte
   101  	for i, err := range e.errs {
   102  		if i > 0 {
   103  			b = append(b, e.split...)
   104  		}
   105  		b = append(b, err.Error()...)
   106  	}
   107  	return string(b)
   108  }
   109  
   110  func (e *joinError) Unwrap() []error {
   111  	return e.errs
   112  }
   113  
   114  var wrapErrorsType = reflect.TypeOf(fmt.Errorf("%w%w", nil, nil))