github.com/aavshr/aws-sdk-go@v1.41.3/aws/awserr/types.go (about) 1 package awserr 2 3 import ( 4 "encoding/hex" 5 "fmt" 6 ) 7 8 // SprintError returns a string of the formatted error code. 9 // 10 // Both extra and origErr are optional. If they are included their lines 11 // will be added, but if they are not included their lines will be ignored. 12 func SprintError(code, message, extra string, origErr error) string { 13 msg := fmt.Sprintf("%s: %s", code, message) 14 if extra != "" { 15 msg = fmt.Sprintf("%s\n\t%s", msg, extra) 16 } 17 if origErr != nil { 18 msg = fmt.Sprintf("%s\ncaused by: %s", msg, origErr.Error()) 19 } 20 return msg 21 } 22 23 // A baseError wraps the code and message which defines an error. It also 24 // can be used to wrap an original error object. 25 // 26 // Should be used as the root for errors satisfying the awserr.Error. Also 27 // for any error which does not fit into a specific error wrapper type. 28 type baseError struct { 29 // Classification of error 30 code string 31 32 // Detailed information about error 33 message string 34 35 // Optional original error this error is based off of. Allows building 36 // chained errors. 37 errs []error 38 } 39 40 // newBaseError returns an error object for the code, message, and errors. 41 // 42 // code is a short no whitespace phrase depicting the classification of 43 // the error that is being created. 44 // 45 // message is the free flow string containing detailed information about the 46 // error. 47 // 48 // origErrs is the error objects which will be nested under the new errors to 49 // be returned. 50 func newBaseError(code, message string, origErrs []error) *baseError { 51 b := &baseError{ 52 code: code, 53 message: message, 54 errs: origErrs, 55 } 56 57 return b 58 } 59 60 // Error returns the string representation of the error. 61 // 62 // See ErrorWithExtra for formatting. 63 // 64 // Satisfies the error interface. 65 func (b baseError) Error() string { 66 size := len(b.errs) 67 if size > 0 { 68 return SprintError(b.code, b.message, "", errorList(b.errs)) 69 } 70 71 return SprintError(b.code, b.message, "", nil) 72 } 73 74 // String returns the string representation of the error. 75 // Alias for Error to satisfy the stringer interface. 76 func (b baseError) String() string { 77 return b.Error() 78 } 79 80 // Code returns the short phrase depicting the classification of the error. 81 func (b baseError) Code() string { 82 return b.code 83 } 84 85 // Message returns the error details message. 86 func (b baseError) Message() string { 87 return b.message 88 } 89 90 // OrigErr returns the original error if one was set. Nil is returned if no 91 // error was set. This only returns the first element in the list. If the full 92 // list is needed, use BatchedErrors. 93 func (b baseError) OrigErr() error { 94 switch len(b.errs) { 95 case 0: 96 return nil 97 case 1: 98 return b.errs[0] 99 default: 100 if err, ok := b.errs[0].(Error); ok { 101 return NewBatchError(err.Code(), err.Message(), b.errs[1:]) 102 } 103 return NewBatchError("BatchedErrors", 104 "multiple errors occurred", b.errs) 105 } 106 } 107 108 // OrigErrs returns the original errors if one was set. An empty slice is 109 // returned if no error was set. 110 func (b baseError) OrigErrs() []error { 111 return b.errs 112 } 113 114 // So that the Error interface type can be included as an anonymous field 115 // in the requestError struct and not conflict with the error.Error() method. 116 type awsError Error 117 118 // A requestError wraps a request or service error. 119 // 120 // Composed of baseError for code, message, and original error. 121 type requestError struct { 122 awsError 123 statusCode int 124 requestID string 125 bytes []byte 126 } 127 128 // newRequestError returns a wrapped error with additional information for 129 // request status code, and service requestID. 130 // 131 // Should be used to wrap all request which involve service requests. Even if 132 // the request failed without a service response, but had an HTTP status code 133 // that may be meaningful. 134 // 135 // Also wraps original errors via the baseError. 136 func newRequestError(err Error, statusCode int, requestID string) *requestError { 137 return &requestError{ 138 awsError: err, 139 statusCode: statusCode, 140 requestID: requestID, 141 } 142 } 143 144 // Error returns the string representation of the error. 145 // Satisfies the error interface. 146 func (r requestError) Error() string { 147 extra := fmt.Sprintf("status code: %d, request id: %s", 148 r.statusCode, r.requestID) 149 return SprintError(r.Code(), r.Message(), extra, r.OrigErr()) 150 } 151 152 // String returns the string representation of the error. 153 // Alias for Error to satisfy the stringer interface. 154 func (r requestError) String() string { 155 return r.Error() 156 } 157 158 // StatusCode returns the wrapped status code for the error 159 func (r requestError) StatusCode() int { 160 return r.statusCode 161 } 162 163 // RequestID returns the wrapped requestID 164 func (r requestError) RequestID() string { 165 return r.requestID 166 } 167 168 // OrigErrs returns the original errors if one was set. An empty slice is 169 // returned if no error was set. 170 func (r requestError) OrigErrs() []error { 171 if b, ok := r.awsError.(BatchedErrors); ok { 172 return b.OrigErrs() 173 } 174 return []error{r.OrigErr()} 175 } 176 177 type unmarshalError struct { 178 awsError 179 bytes []byte 180 } 181 182 // Error returns the string representation of the error. 183 // Satisfies the error interface. 184 func (e unmarshalError) Error() string { 185 extra := hex.Dump(e.bytes) 186 return SprintError(e.Code(), e.Message(), extra, e.OrigErr()) 187 } 188 189 // String returns the string representation of the error. 190 // Alias for Error to satisfy the stringer interface. 191 func (e unmarshalError) String() string { 192 return e.Error() 193 } 194 195 // Bytes returns the bytes that failed to unmarshal. 196 func (e unmarshalError) Bytes() []byte { 197 return e.bytes 198 } 199 200 // An error list that satisfies the golang interface 201 type errorList []error 202 203 // Error returns the string representation of the error. 204 // 205 // Satisfies the error interface. 206 func (e errorList) Error() string { 207 msg := "" 208 // How do we want to handle the array size being zero 209 if size := len(e); size > 0 { 210 for i := 0; i < size; i++ { 211 msg += e[i].Error() 212 // We check the next index to see if it is within the slice. 213 // If it is, then we append a newline. We do this, because unit tests 214 // could be broken with the additional '\n' 215 if i+1 < size { 216 msg += "\n" 217 } 218 } 219 } 220 return msg 221 }