feat: fetcher reads retry_after from body when Cloudflare returns retry-after:0#148
feat: fetcher reads retry_after from body when Cloudflare returns retry-after:0#148kribor wants to merge 1 commit into
Conversation
…ry-after:0 Cloudflare 429 responses set retry-after:0 in the header but encode the actual delay (e.g. 30 s) in the JSON body as retry_after. The header value parses to 0, which previously fell through to exponential backoff and caused premature retries. Now we check res.body.retry_after for any 429/503 where the header-based timeout is ≤ 0.
Review: reading
|
|
The above is Claude's review, after I asked it to check, as it all sounded like a super non-standard behavior. My intention is to not support non-standard things in Fetcher (in our open source libs in general). Instead, proposal is to add a custom hook that will incorporate this custom retry behavior to where it's used (script in NCB3). |
|
Ok, makes sense. In my claude session it sounded like this was well known and consistent cloudflare behavior and caused by technical details in different layers setting headers for body response: WAF sets retry-after: 0 because it doesn't yet know what the real value should be, so that is returned in the body instead. I opened the PR thinking that Cloudflare is so big part of internet that if it's consistent across cloudflare it could make sense to support in fetcher but since it doesn't appear to be the case, makes sense to keep in the hook |
Summary
retry-after: 0in the HTTP header but encode the actual delay (e.g. 30 s) in the JSON body asretry_after0fell through to exponential backoff, causing premature retriesgetRetryTimeoutchecksres.body.retry_afterfor any 429/503 where the header-based timeout resolves to ≤ 0Test plan
retryAfter cloudflare bodycovers the Cloudflare pattern:retry-after: 0header +{ retry_after: 2 }in bodyretryAfterandretryAfter datetests continue to pass