I'm making a request with eleventy-fetch like this:
let response = await EleventyFetch(url, {
duration: "1h",
type: "json"
});
However, sometimes it fails with an error:
Bad response for [url] (429): Too Many Requests (via Error)
I know that I'm requesting too often, so I want to build exponential backoff. However, my initial attempt didn't work:
let response;
let attempts = 0;
const maxAttempts = 5;
while (attempts < maxAttempts) {
try {
response = await EleventyFetch(url, {
duration: "1h",
type: "json"
});
break; // If request is successful, exit the loop
} catch (err) {
if (err.response && err.response.status === 429) {
attempts++;
const waitTime = Math.pow(2, attempts) * 1000; // Exponential backoff
console.warn(`Rate limit exceeded. Retrying in ${waitTime / 1000} seconds...`);
await new Promise(resolve => setTimeout(resolve, waitTime));
} else {
throw err; // If it's not a 429 error, rethrow the error
}
}
}
The error is still being thrown and the exponential backoff never happens. What have I done wrong?
You want to be looking for err.cause
, not err.response
.
The source code of eleventy-fetch's RemoteAssetCache.js shows where the error is generated:
if (!response.ok) {
throw new Error(
`Bad response for ${this.displayUrl} (${response.status}): ${response.statusText}`,
{ cause: response },
);
}
Here, the response is attached to the error as a property cause
.
To make your exponential backoff work, you just need to switch err.response
to err.cause
:
let response;
let attempts = 0;
const maxAttempts = 5;
while (attempts < maxAttempts) {
try {
response = await EleventyFetch(url, {
duration: "1h",
type: "json"
});
break; // If request is successful, exit the loop
} catch (err) {
if (err.cause && err.cause.status === 429) {
attempts++;
const waitTime = Math.pow(2, attempts) * 1000; // Exponential backoff
console.warn(`Rate limit exceeded. Retrying in ${waitTime / 1000} seconds...`);
await new Promise(resolve => setTimeout(resolve, waitTime));
} else {
throw err; // If it's not a 429 error, rethrow the error
}
}
}