github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/vendor_skip/go.mongodb.org/mongo-driver/internal/error.go (about) 1 // Copyright (C) MongoDB, Inc. 2017-present. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); you may 4 // not use this file except in compliance with the License. You may obtain 5 // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 6 7 package internal 8 9 import ( 10 "fmt" 11 ) 12 13 // WrappedError represents an error that contains another error. 14 type WrappedError interface { 15 // Message gets the basic message of the error. 16 Message() string 17 // Inner gets the inner error if one exists. 18 Inner() error 19 } 20 21 // RolledUpErrorMessage gets a flattened error message. 22 func RolledUpErrorMessage(err error) string { 23 if wrappedErr, ok := err.(WrappedError); ok { 24 inner := wrappedErr.Inner() 25 if inner != nil { 26 return fmt.Sprintf("%s: %s", wrappedErr.Message(), RolledUpErrorMessage(inner)) 27 } 28 29 return wrappedErr.Message() 30 } 31 32 return err.Error() 33 } 34 35 // UnwrapError attempts to unwrap the error down to its root cause. 36 func UnwrapError(err error) error { 37 38 switch tErr := err.(type) { 39 case WrappedError: 40 return UnwrapError(tErr.Inner()) 41 case *multiError: 42 return UnwrapError(tErr.errors[0]) 43 } 44 45 return err 46 } 47 48 // WrapError wraps an error with a message. 49 func WrapError(inner error, message string) error { 50 return &wrappedError{message, inner} 51 } 52 53 // WrapErrorf wraps an error with a message. 54 func WrapErrorf(inner error, format string, args ...interface{}) error { 55 return &wrappedError{fmt.Sprintf(format, args...), inner} 56 } 57 58 // MultiError combines multiple errors into a single error. If there are no errors, 59 // nil is returned. If there is 1 error, it is returned. Otherwise, they are combined. 60 func MultiError(errors ...error) error { 61 62 // remove nils from the error list 63 var nonNils []error 64 for _, e := range errors { 65 if e != nil { 66 nonNils = append(nonNils, e) 67 } 68 } 69 70 switch len(nonNils) { 71 case 0: 72 return nil 73 case 1: 74 return nonNils[0] 75 default: 76 return &multiError{ 77 message: "multiple errors encountered", 78 errors: nonNils, 79 } 80 } 81 } 82 83 type multiError struct { 84 message string 85 errors []error 86 } 87 88 func (e *multiError) Message() string { 89 return e.message 90 } 91 92 func (e *multiError) Error() string { 93 result := e.message 94 for _, e := range e.errors { 95 result += fmt.Sprintf("\n %s", e) 96 } 97 return result 98 } 99 100 func (e *multiError) Errors() []error { 101 return e.errors 102 } 103 104 type wrappedError struct { 105 message string 106 inner error 107 } 108 109 func (e *wrappedError) Message() string { 110 return e.message 111 } 112 113 func (e *wrappedError) Error() string { 114 return RolledUpErrorMessage(e) 115 } 116 117 func (e *wrappedError) Inner() error { 118 return e.inner 119 } 120 121 func (e *wrappedError) Unwrap() error { 122 return e.inner 123 }