tekrar
v1.1.0
Published
An abstraction for handling retry strategies, including exponential backoff and custom configurations, for operations that fail.
Downloads
18
Maintainers
Readme
Tekrar
An abstraction for handling retry strategies, including exponential backoff and custom configurations, for operations that fail.
Note: "Tekrar" means "repeat" or "retry" in Turkish, reflecting the module's purpose.
Features
- Simple and lightweight retry mechanism
- Support for both synchronous and asynchronous functions
- Configurable retry count and delay
- Timeout support to limit maximum running time
- Custom error handling and recovery functions
- TypeScript support
Installation
npm install tekrarUsage
Basic Usage
const tekrar = require('tekrar');
// Wrap a function that might fail
const fetchData = tekrar(
async () => {
const response = await fetch('https://api.example.com/data');
if (!response.ok) throw new Error('API request failed');
return response.json();
},
{ count: 3, delay: 1000 },
);
// Use the wrapped function
try {
const data = await fetchData();
console.log('Data:', data);
} catch (error) {
console.error('All retries failed:', error);
}With Recovery Function
const tekrar = require('tekrar');
const sendEmail = tekrar(
async (recipient, content) => {
// Email sending logic that might fail
return emailService.send(recipient, content);
},
{
count: 3,
delay: 2000,
recovery: async (recipient, content) => {
// Log the failure or perform alternative action
console.log(`Failed to send email to ${recipient}, retrying...`);
// You could also modify the content or recipient before the next retry
},
onError: (error) => {
// Log each error
console.error('Email sending error:', error.message);
},
},
);
// Use the wrapped function
try {
await sendEmail('[email protected]', 'Hello, world!');
console.log('Email sent successfully');
} catch (error) {
console.error('Failed to send email after multiple attempts');
}API
tekrar(task, options)
Creates a wrapped function that will retry the given task according to the specified options.
Parameters
task(Function): The function to retry. Can be synchronous or asynchronous.options(Object, optional): Configuration options for retry behavior.count(Number, default: 1): Maximum number of retry attempts.delay(Number, default: 0): Delay in milliseconds between retry attempts.timeout(Number, default: 0): Maximum time in milliseconds for all retry attempts to complete. If exceeded, throws aTimeout Error. Must be greater thandelay. Set to0to disable.recovery(Function, default: () => Promise.resolve()): Function called after each failed attempt, before the next retry. Receives the same arguments as the task.onError(Function, default: () => {}): Function called with each error that occurs. Useful for logging or monitoring.
Returns
A wrapped function that accepts the same arguments as the original task and returns a Promise.
Errors
If all retry attempts fail, the function throws an AggregateError containing all errors that occurred during the retry attempts.
Examples
Retry with Exponential Backoff
const tekrar = require('tekrar');
// Helper function to implement exponential backoff
const withExponentialBackoff = (fn, maxRetries = 5) => {
let retries = 0;
const execute = tekrar(fn, {
count: maxRetries,
delay: 0, // We'll handle the delay in the recovery function
recovery: async (...args) => {
const delay = Math.pow(2, retries) * 100; // Exponential backoff
console.log(`Retrying in ${delay}ms...`);
await new Promise((resolve) => setTimeout(resolve, delay));
retries++;
},
});
return execute;
};
// Usage
const fetchWithRetry = withExponentialBackoff(async (url) => {
const response = await fetch(url);
if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
return response.json();
});
// Use the function
fetchWithRetry('https://api.example.com/data')
.then((data) => console.log('Success:', data))
.catch((error) => console.error('All retries failed:', error));With Timeout
const tekrar = require('tekrar');
const fetchData = tekrar(
async () => {
const response = await fetch('https://api.example.com/data');
if (!response.ok) throw new Error('API request failed');
return response.json();
},
{
count: 5,
delay: 500,
timeout: 3000, // Give up after 3 seconds total
onError: (error) => {
console.error('Attempt failed:', error.message);
},
},
);
try {
const data = await fetchData();
console.log('Data:', data);
} catch (error) {
if (error.message === 'Timeout Error') {
console.error('Operation timed out after 3 seconds');
} else {
console.error('All retries failed:', error);
}
}License
MIT
Author
Timur Sevimli [email protected]
