Skip to content

Commit f45bf51

Browse files
committed
Respect Retry-After HTTP header field in retry mechanism
1 parent 5a24f29 commit f45bf51

File tree

1 file changed

+18
-3
lines changed

1 file changed

+18
-3
lines changed

Sources/HandySwift/Types/RESTClient.swift

+18-3
Original file line numberDiff line numberDiff line change
@@ -249,13 +249,28 @@ public final class RESTClient: Sendable {
249249
return data
250250

251251
case 429:
252-
guard attempt < 5 else { fallthrough }
252+
guard attempt < 5 else { fallthrough }
253+
254+
var sleepSeconds: Double = Double(attempt)
255+
256+
// respect the server retry-after(-ms) value if it exists, allowing values betwen 0.5-5 seconds
257+
if
258+
let retryAfterMillisecondsString = httpResponse.value(forHTTPHeaderField: "retry-after-ms"),
259+
let retryAfterMilliseconds = Double(retryAfterMillisecondsString)
260+
{
261+
sleepSeconds = max(0.5, min(retryAfterMilliseconds, 5))
262+
} else if
263+
let retryAfterString = httpResponse.value(forHTTPHeaderField: "retry-after"),
264+
let retryAfter = Double(retryAfterString)
265+
{
266+
sleepSeconds = max(0.5, min(retryAfter, 5))
267+
}
253268

254269
#if DEBUG
255-
print("Received Status Code 429 'Too Many Requests'. Retrying in \(attempt) second(s)...")
270+
print("Received Status Code 429 'Too Many Requests'. Retrying in \(sleepSeconds) second(s)...")
256271
#endif
257272

258-
try? await Task.sleep(for: .seconds(attempt))
273+
try? await Task.sleep(for: .seconds(sleepSeconds))
259274

260275
let (newData, newResponse) = try await self.performRequest(request, errorContext: errorContext)
261276
return try await self.handle(data: newData, response: newResponse, for: request, errorContext: errorContext, attempt: attempt + 1)

0 commit comments

Comments
 (0)