Gathering detailed insights and metrics for ts-retry-promise
Gathering detailed insights and metrics for ts-retry-promise
Gathering detailed insights and metrics for ts-retry-promise
Gathering detailed insights and metrics for ts-retry-promise
npm install ts-retry-promise
99.1
Supply Chain
99
Quality
77.6
Maintenance
100
Vulnerability
100
License
Module System
Min. Node Version
Typescript Support
Node Version
NPM Version
57 Stars
157 Commits
9 Forks
5 Watching
4 Branches
6 Contributors
Updated on 15 Nov 2024
TypeScript (97.71%)
HTML (2.29%)
Cumulative downloads
Total Downloads
Last day
-7.9%
95,191
Compared to previous day
Last week
-3.1%
499,249
Compared to previous week
Last month
7.2%
2,150,809
Compared to previous month
Last year
38.9%
23,016,476
Compared to previous year
20
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:
1import { retry } from 'ts-retry-promise'; 2 3const result: number = await retry(() => Promise.resolve(1), {retries: 3});
This will instantly start calling your function until it returns a resolved promise, no retries are left or a timeout occurred.
If you want to add retries to an existing function, use the decorator:
1import { retryDecorator } from 'ts-retry-promise'; 2 3const asyncFunction = async (s: String) => s; 4 5const decoratedFunction = retryDecorator(asyncFunction, {timeout: 1}); 6 7const result: string = await decoratedFunction("1");
Here decoratedFunction
is a function with the same signature as asyncFunction
, but will do retries in case of failures.
Both retry
and retryDecorator
take an optional second argument where you can configure the number of retries and timeouts:
1export interface RetryConfig<T> { 2 // number of maximal retry attempts (default: 10) 3 retries?: number | "INFINITELY"; 4 5 // wait time between retries in ms (default: 100) 6 delay?: number; 7 8 // check the result, will retry until true (default: () => true) 9 until?: (t: T) => boolean; 10 11 // log events (default: () => undefined) 12 logger?: (msg: string) => void; 13 14 // overall timeout in ms (default: 60 * 1000) 15 timeout?: number | "INFINITELY"; 16 17 // increase delay with every retry (default: "FIXED") 18 backoff?: "FIXED" | "EXPONENTIAL" | "LINEAR" | ((attempt: number, delay: number) => number); 19 20 // maximal backoff in ms (default: 5 * 60 * 1000) 21 maxBackOff?: number; 22 23 // allows to abort retrying for certain errors, will retry until false (default: () => true) 24 retryIf: (error: any) => boolean 25}
customizeRetry returns a new instance of retry that has the defined default configuration.
1import { customizeRetry } from 'ts-retry-promise'; 2 3const impatientRetry = customizeRetry({timeout: 5}); 4 5await expect(impatientRetry(async () => wait(10))).to.be.rejectedWith("Timeout"); 6 7// another example 8 9const retryUntilNotEmpty = customizeRetry({until: (array: any[]) => array.length > 0}); 10 11const result = await retryUntilNotEmpty(async () => [1, 2]); 12 13expect(result).to.deep.eq([1, 2]);
You can do the same for decorators:
1import { customizeDecorator } from 'ts-retry-promise'; 2 3const asyncFunction = async (s: string) => { 4 await wait(3); 5 return s; 6}; 7 8const impatientDecorator = customizeDecorator({timeout: 1}); 9 10expect(impatientDecorator(asyncFunction)("1")).to.be.rejectedWith("Timeout");
In case retry
failed, an error is thrown.
You can access the error that occurred the last time the function has been retried via the property lastError
:
1retry(async () => throw "1") 2 .catch(err => console.log(err.lastError)); // will print "1"
Wrapped function can throw NotRetryableError
if retrying need to be stopped eventually:
1import { NotRetryableError } from 'ts-retry-promise'; 2 3retry(async () => { throw new NotRetryableError("This error") }, { retries: 'INFINITELY' }) 4 .catch(err => console.log(err.lastError.message)); // will print "This error"
retryDecorator can be used on any function that returns a promise
1const loadUserProfile: (id: number) => Promise<{ name: string }> = async id => ({name: "Mr " + id}); 2 3const robustProfileLoader = retryDecorator(loadUserProfile, {retries: 2}); 4 5const profile = await robustProfileLoader(123);
retry is well suited for acceptance tests (but not restricted to)
1// ts-retry-promise/test/retry-promise.demo.test.ts 2it("will retry until no exception or limit reached", async () => { 3 4 await retry(async () => { 5 const title = await browser.$("h1"); 6 expect(title).to.eq("Loaded"); 7 }); 8 9}); 10 11it("can return a result", async () => { 12 13 const pageTitle = await retry(async () => { 14 const title = await browser.$("h1"); 15 expect(title).to.be.not.empty; 16 return title; 17 }); 18 19 // do some stuff with the result 20 expect(pageTitle).to.eq("Loaded"); 21}); 22 23it("can be configured and has defaults", async () => { 24 25 await retry(async () => { 26 // your code 27 }, {backoff: "LINEAR", retries: 100}); 28 29}); 30 31it("will retry until condition is met or limit reached", async () => { 32 33 await retry( 34 () => browser.$$("ul"), 35 {until: (list) => list.length === 2}); 36 37}); 38 39it("can have a timeout", async () => { 40 41 const promise = retry( 42 () => wait(100), 43 {timeout: 10}, 44 ); 45 46 await expect(promise).to.be.rejectedWith("Timeout"); 47}); 48 49it("can create a customized retry", async () => { 50 const impatientRetry = customizeRetry({timeout: 5}); 51 52 await expect(impatientRetry(async () => wait(10))).to.be.rejectedWith("Timeout"); 53}); 54 55it("can create another customized retry", async () => { 56 const retryUntilNotEmpty = customizeRetry({until: (array: number[]) => array.length > 0}); 57 58 const result = await retryUntilNotEmpty(async () => [1, 2]); 59 60 expect(result).to.deep.eq([1, 2]); 61}); 62 63it("can customize default config", async () => { 64 const originalTimeout = defaultRetryConfig.timeout; 65 try { 66 defaultRetryConfig.timeout = 1; 67 68 await expect(retry(async () => wait(10))).to.be.rejectedWith("Timeout"); 69 } finally { 70 defaultRetryConfig.timeout = originalTimeout; 71 } 72});
Release automation has been setup according this guide.
0.6.1
.latest
tag.No vulnerabilities found.
Reason
no dangerous workflow patterns detected
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
dependency not pinned by hash detected -- score normalized to 4
Details
Reason
Found 5/15 approved changesets -- score normalized to 3
Reason
2 commit(s) and 1 issue activity found in the last 90 days -- score normalized to 2
Reason
9 existing vulnerabilities detected
Details
Reason
detected GitHub workflow tokens with excessive permissions
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
project is not fuzzed
Details
Reason
security policy file not detected
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Score
Last Scanned on 2024-11-18
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More