@@ -153,66 +153,71 @@ func (c *Client) executeRequestWithRetries(method, endpoint string, body, out in
153
153
headerManager .SetRequestHeaders (endpoint )
154
154
headerManager .LogHeaders (c )
155
155
156
- // Calculate the deadline for all retry attempts based on the client configuration.
156
+ // Define a retry deadline based on the client's total retry duration configuration
157
157
totalRetryDeadline := time .Now ().Add (c .clientConfig .ClientOptions .TotalRetryDuration )
158
158
159
- // Execute the HTTP request with retries
160
159
var resp * http.Response
161
160
var retryCount int
162
- var requestStartTime = time .Now ()
163
-
164
- for time .Now ().Before (totalRetryDeadline ) {
161
+ for time .Now ().Before (totalRetryDeadline ) { // Check if the current time is before the total retry deadline
162
+ req = req .WithContext (ctx )
165
163
resp , err = c .do (req , log , method , endpoint )
166
-
167
- // Successful response handling
168
- if err == nil && resp .StatusCode >= 200 && resp .StatusCode < 300 {
169
- log .LogRequestEnd (method , endpoint , resp .StatusCode , time .Since (requestStartTime ))
164
+ // Check for successful status code
165
+ if err == nil && resp .StatusCode >= 200 && resp .StatusCode < 400 {
166
+ if resp .StatusCode >= 300 {
167
+ log .Warn ("Redirect response received" , zap .Int ("status_code" , resp .StatusCode ), zap .String ("location" , resp .Header .Get ("Location" )))
168
+ }
169
+ // Handle the response as successful, even if it's a redirect.
170
170
return resp , c .handleSuccessResponse (resp , out , log , method , endpoint )
171
171
}
172
172
173
- // Log and handle non-retryable errors immediately without retrying
173
+ // Leverage TranslateStatusCode for more descriptive error logging
174
+ statusMessage := status .TranslateStatusCode (resp )
175
+
176
+ // Check for non-retryable errors
174
177
if resp != nil && status .IsNonRetryableStatusCode (resp ) {
175
- log .LogError ( method , endpoint , resp .StatusCode , err , status . TranslateStatusCode ( resp ))
176
- return resp , err
178
+ log .Warn ( "Non-retryable error received" , zap . Int ( "status_code" , resp .StatusCode ), zap . String ( "status_message" , statusMessage ))
179
+ return resp , handleAPIErrorResponse ( resp , log )
177
180
}
178
181
179
- // Handle rate-limiting errors by parsing the 'Retry-After' header and waiting before the next retry
182
+ // Parsing rate limit headers if a rate-limit error is detected
180
183
if status .IsRateLimitError (resp ) {
181
184
waitDuration := parseRateLimitHeaders (resp , log )
182
- log .LogRateLimiting (method , endpoint , resp .Header .Get ("Retry-After" ), waitDuration )
183
- time .Sleep (waitDuration )
184
- continue
185
+ if waitDuration > 0 {
186
+ log .Warn ("Rate limit encountered, waiting before retrying" , zap .Duration ("waitDuration" , waitDuration ))
187
+ time .Sleep (waitDuration )
188
+ continue // Continue to next iteration after waiting
189
+ }
185
190
}
186
191
187
- // Retry the request for transient errors using exponential backoff with jitter
192
+ // Handling retryable errors with exponential backoff
188
193
if status .IsTransientError (resp ) {
189
194
retryCount ++
190
195
if retryCount > c .clientConfig .ClientOptions .MaxRetryAttempts {
191
- // Log max retry attempts reached with structured logging
192
- log .LogError (method , endpoint , resp .StatusCode , err , "Max retry attempts reached" )
193
- break
196
+ log .Warn ("Max retry attempts reached" , zap .String ("method" , method ), zap .String ("endpoint" , endpoint ))
197
+ break // Stop retrying if max attempts are reached
194
198
}
195
199
waitDuration := calculateBackoff (retryCount )
196
- log .LogRetryAttempt ( method , endpoint , retryCount , "Transient error" , waitDuration , err )
197
- time .Sleep (waitDuration )
198
- continue
200
+ log .Warn ( "Retrying request due to transient error" , zap . String ( " method" , method ), zap . String ( " endpoint" , endpoint ), zap . Int ( "retryCount" , retryCount ), zap . Duration ( "waitDuration" , waitDuration ), zap . Error ( err ) )
201
+ time .Sleep (waitDuration ) // Wait before retrying
202
+ continue // Continue to next iteration after waiting
199
203
}
200
204
201
- // Log non-retryable API errors and break the retry loop
205
+ // Handle error responses
202
206
if err != nil || ! status .IsRetryableStatusCode (resp .StatusCode ) {
207
+ if apiErr := handleAPIErrorResponse (resp , log ); apiErr != nil {
208
+ err = apiErr
209
+ }
203
210
log .LogError (method , endpoint , resp .StatusCode , err , status .TranslateStatusCode (resp ))
204
211
break
205
212
}
206
213
}
207
214
208
- // Final error handling after all retries are exhausted
215
+ // Handles final non-API error.
209
216
if err != nil {
210
- // Log the final error after retries with structured logging
211
- log .LogError (method , endpoint , 0 , err , "Final error after retries" )
212
217
return nil , err
213
218
}
214
219
215
- return resp , nil
220
+ return resp , handleAPIErrorResponse ( resp , log )
216
221
}
217
222
218
223
// executeRequest executes an HTTP request using the specified method, endpoint, and request body without implementing
0 commit comments