Security News
JSR Working Group Kicks Off with Ambitious Roadmap and Plans for Open Governance
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
ts-retry-promise
Advanced tools
The ts-retry-promise npm package provides a way to retry promises with customizable options. It is useful for handling transient errors in asynchronous operations by retrying the operation until it succeeds or a maximum number of retries is reached.
Basic Retry
This feature allows you to retry a promise-based function a specified number of times. In this example, the fetchData function simulates an API call that may fail. The retry function will attempt to call fetchData up to 3 times before giving up.
const retry = require('ts-retry-promise');
const fetchData = () => {
return new Promise((resolve, reject) => {
// Simulate an API call that may fail
if (Math.random() > 0.5) {
resolve('Data fetched successfully');
} else {
reject('Fetch failed');
}
});
};
retry(fetchData, { retries: 3 })
.then(result => console.log(result))
.catch(err => console.error(err));
Exponential Backoff
This feature allows you to retry a promise-based function with exponential backoff. The delay between retries increases exponentially. In this example, the initial delay is 1000ms and it doubles with each retry.
const retry = require('ts-retry-promise');
const fetchData = () => {
return new Promise((resolve, reject) => {
// Simulate an API call that may fail
if (Math.random() > 0.5) {
resolve('Data fetched successfully');
} else {
reject('Fetch failed');
}
});
};
retry(fetchData, { retries: 3, delay: 1000, factor: 2 })
.then(result => console.log(result))
.catch(err => console.error(err));
Custom Retry Logic
This feature allows you to define custom logic to determine if a promise should be retried. In this example, the shouldRetry function checks if the error message is 'Fetch failed' to decide whether to retry the fetchData function.
const retry = require('ts-retry-promise');
const fetchData = () => {
return new Promise((resolve, reject) => {
// Simulate an API call that may fail
if (Math.random() > 0.5) {
resolve('Data fetched successfully');
} else {
reject('Fetch failed');
}
});
};
const shouldRetry = (err) => {
// Custom logic to determine if the error is retryable
return err === 'Fetch failed';
};
retry(fetchData, { retries: 3, shouldRetry })
.then(result => console.log(result))
.catch(err => console.error(err));
The promise-retry package provides similar functionality for retrying promises. It allows for customizable retry strategies, including exponential backoff. Compared to ts-retry-promise, promise-retry offers a more flexible API for defining retry strategies.
The async-retry package is another alternative for retrying asynchronous operations. It supports various retry strategies and is highly configurable. It is similar to ts-retry-promise but offers additional features like custom retry strategies and more detailed error handling.
The retry package provides a comprehensive set of tools for retrying operations. It supports both synchronous and asynchronous retries, with customizable options for delay, retries, and backoff strategies. It is more feature-rich compared to ts-retry-promise, making it suitable for more complex retry scenarios.
retry for functions returning a promise
Install with yarn:
yarn add ts-retry-promise
Install with npm:
npm install --save ts-retry-promise
Then you can import it with:
import { retry } from 'ts-retry-promise';
function retry<T>(f: () => Promise<T>, config?: RetryConfig<T>): Promise<T> {}
retry will repeatedly call f until a resolved Promise is returned. Optionally a predicate can be specified, against which the result will be checked.
Several aspects of the execution can be configured:
export interface RetryConfig<T> {
// number of maximal retry attempts (default: 10)
retries?: number | "INFINITELY";
// wait time between retries in ms (default: 100)
delay?: number;
// check the result, will retry until true (default: () => true)
until?: (t: T) => boolean;
// log events (default: () => undefined)
logger?: (msg: string) => void;
// overall timeout in ms (default: 60 * 1000)
timeout?: number;
// increase delay with every retry (default: "FIXED")
backoff?: "FIXED" | "EXPONENTIAL" | "LINEAR" | ((attempt: number, delay: number) => number);
// maximal backoff in ms (default: 5 * 60 * 1000)
maxBackOff?: number;
}
customizeRetry returns a new instance of retry that has the defined default configuration.
const impatientRetry = customizeRetry({timeout: 5});
await expect(impatientRetry(async () => wait(10))).to.be.rejectedWith("Timeout");
// another example
const retryUntilNotEmpty = customizeRetry({until: (array: any[]) => array.length > 0});
const result = await retryUntilNotEmpty(async () => [1, 2]);
expect(result).to.deep.eq([1, 2]);
retry is well suited for acceptance tests (but not restricted to).
// ts-retry-promise/test/retry-promise.demo.test.ts
it("will retry until no exception or limit reached", async () => {
await retry(async () => {
const title = await browser.$("h1");
expect(title).to.eq("Loaded");
});
});
it("can return a result", async () => {
const pageTitle = await retry(async () => {
const title = await browser.$("h1");
expect(title).to.be.not.empty;
return title;
});
// do some stuff with the result
expect(pageTitle).to.eq("Loaded");
});
it("can be configured and has defaults", async () => {
await retry(async () => {
// your code
}, {backoff: "LINEAR", retries: 100});
});
it("will retry until condition is met or limit reached", async () => {
await retry(
() => browser.$$("ul"),
{until: (list) => list.length === 2});
});
it("can have a timeout", async () => {
const promise = retry(
() => wait(100),
{timeout: 10},
);
await expect(promise).to.be.rejectedWith("Timeout");
});
it("can create a customized retry", async () => {
const impatientRetry = customizeRetry({timeout: 5});
await expect(impatientRetry(async () => wait(10))).to.be.rejectedWith("Timeout");
});
it("can create another customized retry", async () => {
const retryUntilNotEmpty = customizeRetry({until: (array: number[]) => array.length > 0});
const result = await retryUntilNotEmpty(async () => [1, 2]);
expect(result).to.deep.eq([1, 2]);
});
it("can customize default config", async () => {
const originalTimeout = defaultRetryConfig.timeout;
try {
defaultRetryConfig.timeout = 1;
await expect(retry(async () => wait(10))).to.be.rejectedWith("Timeout");
} finally {
defaultRetryConfig.timeout = originalTimeout;
}
});
FAQs
retry for functions returning a promise
We found that ts-retry-promise demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
At its inaugural meeting, the JSR Working Group outlined plans for an open governance model and a roadmap to enhance JavaScript package management.
Security News
Research
An advanced npm supply chain attack is leveraging Ethereum smart contracts for decentralized, persistent malware control, evading traditional defenses.
Security News
Research
Attackers are impersonating Sindre Sorhus on npm with a fake 'chalk-node' package containing a malicious backdoor to compromise developers' projects.