Promised Retry
Promised Retry is a lightweight, generic utility for implementing promise-based retry mechanisms. It is particularly useful for scenarios requiring robust connection handling, such as ensuring database or message queue availability, by automatically retrying failed operations. The current stable version is 0.6.0. The package has an irregular release cadence, often driven by updates to its minimum Node.js version requirement. Key differentiators include highly configurable retry delays (minimum, base, exponent, or a custom function), an optional retry limit, and lifecycle hooks for setup, successful attempts, and graceful shutdown. It also provides methods to explicitly reset or end the retry process. This library focuses purely on retry logic without imposing additional runtime dependencies.
Common errors
-
TypeError: (0 , promised_retry_1.default) is not a constructor
cause Incorrect ESM import syntax for a CommonJS default export.fixChange `import { Retry } from 'promised-retry';` to `import Retry from 'promised-retry';`. -
TypeError: Retry is not a constructor (when using named import in ESM)
cause Attempting to import `Retry` as a named export from a CommonJS module that only provides a default export.fixUse the default import syntax for ESM: `import Retry from 'promised-retry';`. -
This package requires Node.js version 16.0.0 or higher.
cause Running `promised-retry@0.6.0` or newer on an unsupported Node.js version.fixUpgrade your Node.js runtime to version 16.0.0 or later. If using `nvm`, run `nvm install 16` and `nvm use 16` (or a newer version).
Warnings
- breaking Version 0.6.0 introduces a breaking change by requiring Node.js version 16.0.0 or higher. Older Node.js versions are no longer supported.
- breaking Version 0.5.0 introduced a breaking change by requiring Node.js version 14.x or higher. If you are on an older Node.js version, you must upgrade.
- breaking Version 0.4.0 introduced a breaking change by requiring Node.js version 12.x or higher. Earlier Node.js versions are not supported.
- gotcha This package is explicitly CommonJS (`Module type: CJS` in README). While it can be imported in ESM projects, ensure you use the correct default import syntax to avoid `TypeError`s.
Install
-
npm install promised-retry -
yarn add promised-retry -
pnpm add promised-retry
Imports
- Retry
const Retry = require('promised-retry') - Retry
import { Retry } from 'promised-retry'import Retry from 'promised-retry'
- RetryOptions
import { RetryOptions } from 'promised-retry'import type { RetryOptions } from 'promised-retry'
Quickstart
const Retry = require('promised-retry');
const { Client } = require('pg');
const dbConfig = {
user: process.env.DB_USER ?? 'testuser',
host: process.env.DB_HOST ?? 'localhost',
database: process.env.DB_NAME ?? 'testdb',
password: process.env.DB_PASSWORD ?? 'testpassword',
port: parseInt(process.env.DB_PORT ?? '5432', 10),
};
let currentDbClient = null;
const channels = ['my_channel', 'another_channel'];
const retryInstance = new Retry({
name: 'PostgreSQL Connection',
try: async () => {
const db = new Client(dbConfig);
db.on('error', (err) => {
console.error('DB Client error, resetting retry:', err.message);
currentDbClient = null; // Mark client as invalid
retryInstance.reset();
// Optionally, if you want to immediately re-try after a connection error:
// retryInstance.try();
});
await db.connect();
console.log('Database connected successfully!');
return db; // Return the connected client
},
success: db => {
currentDbClient = db;
db.on('notification', (msg) => {
console.log(`Received notification on channel ${msg.channel}: ${msg.payload}`);
});
channels.forEach(channel => {
db.query('LISTEN ' + channel);
console.log(`Listening on channel: ${channel}`);
});
console.log('Successfully established DB connection and listeners.');
},
end: async db => {
if (db) {
console.log('Ending database connection...');
await db.end();
console.log('Database connection ended.');
}
},
retryMin: 1000, // minimum 1 second delay
retryBase: 1.5, // exponential backoff
retryExponent: 5 // max exponent for delay calculation
});
async function initializeDbConnection() {
try {
await retryInstance.try();
console.log('Initial database connection established.');
} catch (error) {
console.error('Failed to establish database connection after retries:', error.message);
}
}
initializeDbConnection();
// Example of how to end the retry mechanism (e.g., on application shutdown)
process.on('SIGINT', async () => {
console.log('Received SIGINT. Shutting down...');
await retryInstance.end(currentDbClient);
process.exit(0);
});