Mastering JavaScript Async Error Handling with Custom Retry Logic
Learn how to handle asynchronous errors in JavaScript by building custom retry logic to make your apps more reliable and resilient.
When working with asynchronous JavaScript, such as fetching data from an API, errors can occur due to various reasons like network issues or server problems. Handling these errors properly is crucial to building reliable applications. One effective way to improve error handling is by implementing custom retry logic that attempts the operation multiple times before failing.
In this article, we'll explore a simple yet powerful approach to retry failed async operations using JavaScript's async/await syntax. You’ll learn how to create a reusable function that retries requests and handles errors gracefully.
Let's start by creating a function that simulates an unreliable asynchronous task. This function will randomly fail or succeed to help us test our retry logic.
async function unreliableAsyncTask() {
return new Promise((resolve, reject) => {
// Simulate a 50% chance of failure
const succeed = Math.random() > 0.5;
setTimeout(() => {
if (succeed) {
resolve('Success!');
} else {
reject(new Error('Something went wrong'));
}
}, 500);
});
}Now, we’ll create our custom retry function. This function takes an async function as a parameter, along with the maximum number of retries and an optional delay between retries.
async function retryAsync(fn, retries = 3, delay = 1000) {
for (let attempt = 1; attempt <= retries; attempt++) {
try {
// Attempt to execute the async function
const result = await fn();
return result; // Return if successful
} catch (error) {
// If last attempt, throw the error
if (attempt === retries) {
throw error;
}
console.log(`Attempt ${attempt} failed. Retrying in ${delay}ms...`);
// Wait before retrying
await new Promise(res => setTimeout(res, delay));
}
}
}Finally, let's use our retryAsync function with the unreliableAsyncTask. This will automatically retry the task up to three times before throwing an error.
retryAsync(unreliableAsyncTask, 3, 1000)
.then(result => console.log('Final result:', result))
.catch(error => console.error('Failed after retries:', error.message));This pattern is incredibly useful when dealing with APIs or any async tasks prone to temporary failures. You can customize the number of retries and delay between attempts to suit your application’s needs.
To summarize, mastering async error handling with custom retry logic involves wrapping your async calls in a retry loop, catching errors, and optionally adding delays between retries. This makes your application more robust and resistant to transient errors.