Implement fetchRetry with a bounded number of retries and a delay
Implement fetchRetry(url, retries, delay) that uses the Fetch API and retries on failure. Requirements: resolve with the Response on the first success; on a failed attempt wait delay ms, then retry; give up after retries attempts and reject with the last error. Treat a network error (a rejected fetch) as a failure. Do not retry forever; the total attempts must be bounded.
function fetchRetry(url, retries, delay) {
// your code here
}
Write the implementation.
Wrap the attempt in a recursive (or looped) helper. try { return await fetch(url); } catch (err): if retries <= 0, rethrow the last error; otherwise await a delay-ms timer (a promise around setTimeout) and recurse with retries - 1.
- ✗Looping without a counter, retrying forever on a permanently failing URL
- ✗Forgetting to
awaitthe delay timer, so retries fire back-to-back - ✗Swallowing the last error instead of rejecting once retries are exhausted
- →How would you add exponential backoff instead of a fixed delay?
- →Why might you retry only on certain status codes rather than every failure?
Solution
A recursive attempt that decrements the counter and waits between retries.
const wait = (ms) => new Promise((r) => setTimeout(r, ms)); // promise around setTimeout
async function fetchRetry(url, retries, delay) {
try {
return await fetch(url); // first success resolves at once
} catch (err) {
if (retries <= 0) throw err; // retries exhausted → last error
await wait(delay); // wait before retrying
return fetchRetry(url, retries - 1, delay);
}
}
How it works
Each attempt awaits fetch(url); on success the Response returns immediately. On a rejection (network error) we check the counter: at zero we rethrow the last error, otherwise we wait delay ms and recurse with retries - 1. This bounds total attempts and ends in a rejection with the last error rather than an infinite loop.