In this lesson, you will learn how to implement basic retry logic and robust error-handling routines to maintain database connectivity when your network environment is unstable.
Why Timeouts Happen
Even with well-configured connection pools, network fluctuations or database load spikes can cause your application’s request to "hang." If a database driver doesn't receive a response within your defined timeout threshold, it throws an error. Rather than crashing your application or returning an immediate 500 error to the user, you can implement a retry strategy.
The "Retry with Backoff" Pattern
The most effective way to handle a transient connection failure is to attempt the connection again, but with a slight delay. This gives the database a moment to recover.
Here is how you might implement a simple retry loop for a database query:
async function queryWithRetry(db, sql, params, retries = 3, delay = 1000) {
for (let i = 0; i < retries; i++) {
try {
return await db.query(sql, params);
} catch (err) {
if (err.code === 'ETIMEDOUT' && i < retries - 1) {
console.log(`Connection failed, retrying in ${delay}ms...`);
await new Promise(res => setTimeout(res, delay));
continue;
}
throw err; // Permanent error or out of retries
}
}
}
Implementing Robust Error Handling
When a connection timeout occurs, your routine should distinguish between transient and permanent failures:
- Identify the Error: Check if the error code is a network-related issue (like
ETIMEDOUTorECONNREFUSED). - Graceful Degradation: If the retries fail, your application should log the error, alert your monitoring system, and return a user-friendly message rather than letting the stack trace leak to the client.
- Circuit Breaking (Conceptually): If retries keep failing, stop trying for a set duration. This prevents your Node.js application from flooding a struggling database with even more requests, which can lead to a "thundering herd" problem.
By wrapping your database calls in these routines, you ensure that your service remains resilient against the inherent volatility of network connections.
Key Takeaway: Use controlled retry loops with incremental delays to gracefully handle transient network timeouts without overwhelming your database.