github.com/TBD54566975/ftl@v0.219.0/internal/errors/errors.go (about) 1 package errors 2 3 import ( 4 "errors" 5 "strings" 6 7 "golang.org/x/exp/maps" 8 ) 9 10 // UnwrapAll recursively unwraps all errors in err, including all intermediate errors. 11 // 12 //nolint:errorlint 13 func UnwrapAll(err error) []error { 14 out := []error{} 15 if inner, ok := err.(interface{ Unwrap() []error }); ok { 16 for _, e := range inner.Unwrap() { 17 out = append(out, UnwrapAll(e)...) 18 } 19 return out 20 } 21 if inner, ok := err.(interface{ Unwrap() error }); ok && inner.Unwrap() != nil { 22 out = append(out, UnwrapAll(inner.Unwrap())...) 23 } 24 out = append(out, err) 25 return out 26 } 27 28 // Innermost returns true if err cannot be further unwrapped. 29 // 30 //nolint:errorlint 31 func Innermost(err error) bool { 32 if err, ok := err.(interface{ Unwrap() []error }); ok && len(err.Unwrap()) > 0 { 33 return false 34 } 35 if err, ok := err.(interface{ Unwrap() error }); ok && err.Unwrap() != nil { 36 return false 37 } 38 return true 39 } 40 41 func Join(errs ...error) error { return errors.Join(errs...) } 42 43 func New(text string) error { return errors.New(text) } 44 45 func As(err error, target interface{}) bool { return errors.As(err, target) } 46 47 func Is(err, target error) bool { return errors.Is(err, target) } 48 49 func Unwrap(err error) error { return errors.Unwrap(err) } 50 51 // DeduplicateErrors de-duplicates equivalent errors. 52 func DeduplicateErrors(merr []error) []error { 53 set := map[string]error{} 54 for _, err := range merr { 55 for _, subErr := range UnwrapAll(err) { 56 set[strings.TrimSpace(subErr.Error())] = subErr 57 } 58 } 59 return maps.Values(set) 60 }