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))