Error handling
Learn how to handle errors when using node-redis.
node-redis uses promises for error handling. Most Redis JavaScript examples throughout the documentation mainly show the "happy path" and omit error handling for brevity. This page shows how to apply error handling techniques in node-redis for real world code. For an overview of some common general error types and strategies for handling them, see Error handling. See also Production usage for more information on connection management, timeouts, and other aspects of app reliability.
Common error types
node-redis throws errors as rejected promises. Common error types include:
| Error | When it occurs | Recoverable | Recommended action |
|---|---|---|---|
ECONNREFUSED |
Connection refused | ✅ | Retry with backoff or fall back |
ETIMEDOUT |
Command timeout | ✅ | Retry with backoff |
ECONNRESET |
Connection reset by peer | ✅ | Retry with backoff |
EAI_AGAIN |
DNS resolution failure | ✅ | Retry with backoff |
ReplyError (WRONGTYPE) |
Type mismatch | ❌ | Fix schema or code |
ReplyError (BUSY, TRYAGAIN, LOADING) |
Redis busy/loading | ⚠️ | Retry with backoff (bounded) |
See Categories of errors for a more detailed discussion of these errors and their causes.
Async/await in examples
The examples on this page and throughout the node-redis docs use async/await
style for clarity.
// Using async/await (shown in examples below)
try {
const result = await client.get(key);
// Handle success
} catch (error) {
// Handle error
}
Alternatively, you can use promise chains with .then() and .catch():
// Using promise chains (equivalent approach)
client.get(key)
.then(result => {
// Handle success
})
.catch(error => {
// Handle error
});
Error events
Node-Redis provides multiple events to handle various scenarios, among which the most critical is the error event.
This event is triggered whenever an error occurs within the client.
It is crucial to listen for error events.
If a client does not register at least one error listener and an error occurs, the system will throw that error, potentially causing the Node.js process to exit unexpectedly. See the EventEmitter docs for more details.
const client = createClient({
// ... client options
});
// Always ensure there's a listener for errors in the client to prevent process crashes due to unhandled errors
client.on('error', error => {
console.error(`Redis client error:`, error);
});
Applying error handling patterns
The Error handling overview describes four common error handling patterns. The sections below show how to implement these patterns in node-redis:
Pattern 1: Fail fast
Catch specific errors that represent unrecoverable errors and re-throw them (see Pattern 1: Fail fast for a full description).
try {
await client.get(key);
} catch (err) {
if (err.name === 'ReplyError' && /WRONGTYPE|ERR /.test(err.message)) {
throw err; // Fix code or data type
}
throw err;
}
Pattern 2: Graceful degradation
Catch connection errors and fall back to an alternative (see Pattern 2: Graceful degradation for a full description).
try {
const val = await client.get(key);
if (val != null) return val;
} catch (err) {
if (['ECONNREFUSED','ECONNRESET','ETIMEDOUT','EAI_AGAIN'].includes(err.code)) {
logger.warn('Cache unavailable; falling back to DB');
return database.get(key);
}
throw err;
}
return database.get(key);
Pattern 3: Retry with backoff
Retry on temporary errors like timeouts (see Pattern 3: Retry with backoff for a full description).
async function getWithRetry(key, { attempts = 3, baseDelayMs = 100 } = {}) {
let delay = baseDelayMs;
for (let i = 0; i < attempts; i++) {
try {
return await client.get(key);
} catch (err) {
if (
i < attempts - 1 &&
(['ETIMEDOUT','ECONNRESET','EAI_AGAIN'].includes(err.code) ||
(err.name === 'ReplyError' && /(BUSY|TRYAGAIN|LOADING)/.test(err.message)))
) {
await new Promise(r => setTimeout(r, delay));
delay *= 2;
continue;
}
throw err;
}
}
}
Note that you can also configure node-redis to reconnect to the server automatically when the connection is lost. See Reconnect after disconnection for more information.
Pattern 4: Log and continue
Log non-critical errors and continue (see Pattern 4: Log and continue for a full description).
try {
await client.setEx(key, 3600, value);
} catch (err) {
if (['ECONNREFUSED','ECONNRESET','ETIMEDOUT','EAI_AGAIN'].includes(err.code)) {
logger.warn(`Failed to cache ${key}, continuing without cache`);
} else {
throw err;
}
}