Implement retry logic in JavaScript
This post will discuss how to implement a retry logic in JavaScript.
Retry logic is a technique that allows a program to retry an operation that may fail due to transient errors, such as network issues, timeouts, or server errors. Retry logic can improve the reliability and robustness of a program by handling these errors gracefully and giving the operation another chance to succeed. There are different ways to implement retry logic in JavaScript, depending on the requirements and preferences of the programmer. Here are some possible functions:
1. Using a recursive function
A recursive function is a function that calls itself until a base case is reached. This can be used to implement retry logic by passing the number of attempts and the delay time as parameters, and decrementing or increasing them accordingly in each recursive call. For example:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
// Define a function that takes another function as an argument and // returns a new function that implements retry logic const retry = (fn, maxAttempts, delay) => { // Define a recursive function that takes the current attempt as an argument const execute = async (attempt) => { try { // Try to execute the original function and return the result return await fn(); } catch (err) { // If an error occurs, check if the current attempt is less than // or equal to the maximum number of attempts if (attempt <= maxAttempts) { // If yes, increment the current attempt and calculate the next delay time const nextAttempt = attempt + 1; // We can use any backoff strategy here, such as exponential or linear const nextDelay = delay * 2; console.log(`Retrying after ${nextDelay} ms due to:`, err); // Wait for the next delay time and then call the recursive function again // with the next attempt return new Promise((resolve) => setTimeout(() => resolve(execute(nextAttempt)), nextDelay)); } else { // If no, throw the error throw err; } } }; // Return the recursive function with the initial attempt as 1 return() => execute(1); }; // Define a function that may fail randomly const unreliable = () => { return new Promise((resolve, reject) => { setTimeout(() => { if (Math.random() < 0.5) { resolve("Success"); } else { reject("Failure"); } }, 1000); }); }; // Wrap the unreliable function with retry logic // Retry up to 3 times with an initial delay of 1000 ms const reliable = retry(unreliable, 3, 1000); // Call the reliable function and handle the result or error reliable() .then((result) => console.log(result)) .catch((err) => console.log(err)); |
Sample Output:
Retrying after 2000 ms due to: Failure
Retrying after 2000 ms due to: Failure
Success
2. Using a loop
A loop is a control flow statement that repeats a block of code until a condition is met. This can be used to implement retry logic by using a variable to store the number of attempts and updating it in each iteration. For example:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
// Define a function that takes another function as an argument and // returns a new function that implements retry logic const retry = (fn, maxAttempts, delay) => { // Return a new function that uses a loop to retry the original function return async() => { // Declare a variable to store the current attempt let attempt = 1; // Declare a variable to store the result or error let result; // Use a while loop to repeat until the maximum number of attempts is reached // or the original function succeeds while (attempt <= maxAttempts) { try { // Try to execute the original function and assign the result to variable result = await fn(); // Break out of the loop if successful break; } catch (err) { // If an error occurs, assign the error to the variable // and increment the current attempt result = err; attempt++; // Wait for the delay time before continuing the loop await new Promise((resolve) => setTimeout(resolve, delay)); } } // Check if the result is an error or not if (result instanceof Error) { // If yes, throw the error throw result; } else { // If no, return the result return result; } }; }; // Define a function that may fail randomly const unreliable = () => { return new Promise((resolve, reject) => { setTimeout(() => { if (Math.random() < 0.5) { resolve("Success"); } else { console.log(`Retrying after ${delay} ms due to failure`); reject("Failure"); } }, 1000); }); }; // Wrap the unreliable function with retry logic // Retry up to 3 times with an initial delay of 1000 ms const delay = 1000; const reliable = retry(unreliable, 3, 1000); // Call the reliable function and handle the result or error reliable() .then((result) => console.log(result)) .catch((err) => console.log(err)); |
Sample Output:
Retrying after 1000 ms due to failure
Success
3. Using a library
Finally, we can use a third-party library that provides various functions and utilities for implementing retry logic in JavaScript, such as async-retry, p-retry, axios-retry, etc. These libraries often have their own options and parameters to customize the retry behavior and strategy. We can install them using npm or include it in our HTML file using a script tag. Here’s an example using async-retry:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
// Using async-retry library const retry = require("async-retry"); const fetch = require("node-fetch"); // An example operation that returns a promise async function fetchSomething() { return fetch("https://example.com/api/something"); } // Call the retry function with the operation and some options retry(async bail => { // Try to perform the operation const result = await fetchSomething(); // Check if the result is valid if (!result.ok) { // If not, throw an error to trigger a retry throw new Error("Invalid result"); } // If yes, return the result return result; }, { // Specify the number of retries retries: 3, // Specify the retry factor for exponential backoff factor: 2, // Specify the minimum delay between retries in milliseconds minTimeout: 1000, }) .then(result => { // Handle the successful result console.log("Operation succeeded:", result); }) .catch(error => { // Handle the final error console.error("Operation failed:", error); }); |
That’s all about implementing a retry logic in JavaScript.
Thanks for reading.
To share your code in the comments, please use our online compiler that supports C, C++, Java, Python, JavaScript, C#, PHP, and many more popular programming languages.
Like us? Refer us to your friends and support our growth. Happy coding :)