github.com/wfusion/gofusion@v1.1.14/common/utils/candy.go (about) 1 package utils 2 3 import ( 4 "io" 5 "runtime/debug" 6 7 "github.com/pkg/errors" 8 ) 9 10 func Catch(fn any) (isPanic bool, err error) { 11 defer func() { 12 r := recover() 13 if r == nil { 14 return 15 } 16 17 isPanic = true 18 switch v := r.(type) { 19 case error: 20 err = errors.Wrapf(v, "panic when call Catch function =>\n%s", debug.Stack()) 21 default: 22 err = errors.Errorf("panic when call Catch function: %s =>\n%s", r, debug.Stack()) 23 } 24 }() 25 26 // check supported function 27 var v any 28 switch f := fn.(type) { 29 case func(): 30 f() 31 case func() error: 32 err = f() 33 case func() (any, error): 34 v, err = f() 35 default: 36 panic(errors.Errorf("unsupported function signature %T", fn)) 37 } 38 39 if err != nil { 40 return 41 } 42 if ve, ok := v.(error); ok { 43 err = ve 44 } 45 return 46 } 47 48 func CheckIfAny(fnList ...func() error) error { 49 for _, fn := range fnList { 50 if err := fn(); err != nil { 51 return err 52 } 53 } 54 return nil 55 } 56 57 func IfAny(fnList ...func() bool) { 58 for _, fn := range fnList { 59 if fn() { 60 break 61 } 62 } 63 } 64 65 func MustSuccess(err error) { 66 if err != nil { 67 panic(err) 68 } 69 } 70 71 func Must[T any](out T, err error) T { 72 if err != nil { 73 panic(err) 74 } 75 return out 76 } 77 78 func MustOk[T any](out T, ok bool) T { 79 if !ok { 80 panic(errors.Errorf("get %T with ok is false", out)) 81 } 82 return out 83 } 84 85 type closerA interface{ Close() } 86 type closerB[T any] interface{ Close() T } 87 88 func CloseAnyway[T any](closer T) { 89 if any(closer) == nil { 90 return 91 } 92 93 switch c := any(closer).(type) { 94 case io.Closer: 95 _ = c.Close() 96 case closerA: 97 c.Close() 98 case closerB[T]: 99 c.Close() 100 } 101 } 102 103 type flusherA interface{ Flush() } 104 type flusherB interface{ Flush() error } 105 106 func FlushAnyway[T any](flusher T) { 107 if any(flusher) == nil { 108 return 109 } 110 111 switch f := any(flusher).(type) { 112 case flusherA: 113 f.Flush() 114 case flusherB: 115 _ = f.Flush() 116 } 117 } 118 119 func ErrIgnore(src error, ignored ...error) (dst error) { 120 for _, target := range ignored { 121 if errors.Is(src, target) { 122 return 123 } 124 } 125 return src 126 } 127 128 type lookupByFuzzyKeywordFuncType[T any] interface { 129 func(string) T | 130 func(string) (T, bool) | 131 func(string) (T, error) 132 } 133 134 func LookupByFuzzyKeyword[T any, F lookupByFuzzyKeywordFuncType[T]](lookup F, keyword string) (v T) { 135 fn := WrapFunc1[T](lookup) 136 for _, k := range FuzzyKeyword(keyword) { 137 if v = fn(k); !IsBlank(v) { 138 return 139 } 140 } 141 return 142 }