@yveskaufmann/retry
Advanced tools
Comparing version 1.1.0 to 1.1.1
@@ -0,1 +1,5 @@ | ||
import { Clazz } from './types'; | ||
export interface RetryCondition<T = unknown> { | ||
(result: T, err: Error): boolean; | ||
} | ||
/** | ||
@@ -36,3 +40,3 @@ * Options to configure a retriable operation. | ||
*/ | ||
retryWhen: (result: T, err: Error) => boolean; | ||
retryWhen: RetryCondition; | ||
/** | ||
@@ -42,3 +46,5 @@ * Will be invoked after each failed attempt. | ||
* @param attempt The number of the attempt | ||
* @param attempt The number of the attempt. | ||
* @param attemptsLeft The number of attempts left. | ||
* @param result The returned value from the retryable operation, that is considered be a reason to perform a retry | ||
@@ -48,3 +54,3 @@ * @param err The cause of the failed attempt | ||
*/ | ||
onFailedAttempt?: (attempt: number, result: T, err: Error) => void; | ||
onFailedAttempt?: (attempt: number, attemptsLeft: number, result: T, err: Error) => void; | ||
/** | ||
@@ -97,4 +103,12 @@ * Calculates the delay between retries in milliseconds. | ||
onNullResult(): (result: unknown, err: Error) => boolean; | ||
custom(): { | ||
"__#1@#retryableErrors": Array<Clazz<Error>>; | ||
"__#1@#retyableConditions": Array<RetryCondition>; | ||
onError(...err: Clazz<Error>[]): this; | ||
onCondition(...condition: RetryCondition[]): this; | ||
toCondition(): (result: unknown, err: Error) => boolean; | ||
}; | ||
} | ||
export declare class Retry { | ||
private static readonly localAsyncStorage; | ||
/** | ||
@@ -129,2 +143,20 @@ * List of built-in delays | ||
} & RetryOptions<T>): Promise<T>; | ||
/** | ||
* @returns The number of the current attempt. | ||
* | ||
* The method is only invocateable inside Retryable operation | ||
*/ | ||
static getAttempt(): number; | ||
/** | ||
* @returns The number of left attempts including the current attempt. | ||
* * | ||
* The method is only invocateable inside Retryable operation | ||
*/ | ||
static getAttemptLeft(): number; | ||
/** | ||
* @returns true if the current attempt is the last one. | ||
* | ||
* The method is only invocateable inside Retryable operation | ||
*/ | ||
static isLastAttempt(): boolean; | ||
} | ||
@@ -131,0 +163,0 @@ /** |
@@ -11,4 +11,10 @@ "use strict"; | ||
}; | ||
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); | ||
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Retryable = exports.MaxRetryAttemptsReached = exports.Retry = void 0; | ||
const async_hooks_1 = require("async_hooks"); | ||
const wait_1 = require("./wait"); | ||
@@ -66,2 +72,38 @@ /** | ||
} | ||
custom() { | ||
var _retryableErrors, _retyableConditions, _a; | ||
return new (_a = class { | ||
constructor() { | ||
_retryableErrors.set(this, []); | ||
_retyableConditions.set(this, []); | ||
} | ||
onError(...err) { | ||
__classPrivateFieldGet(this, _retryableErrors, "f").push(...err); | ||
return this; | ||
} | ||
onCondition(...condition) { | ||
__classPrivateFieldGet(this, _retyableConditions, "f").push(...condition); | ||
return this; | ||
} | ||
toCondition() { | ||
return (result, err) => { | ||
if (err) { | ||
if (__classPrivateFieldGet(this, _retryableErrors, "f").length > 0 && | ||
__classPrivateFieldGet(this, _retryableErrors, "f").some((retryableError) => err instanceof retryableError)) { | ||
return true; | ||
} | ||
} | ||
if (result !== undefined) { | ||
if (__classPrivateFieldGet(this, _retyableConditions, "f").length > 0 && __classPrivateFieldGet(this, _retyableConditions, "f").some((cond) => cond(result, err))) { | ||
return true; | ||
} | ||
} | ||
return false; | ||
}; | ||
} | ||
}, | ||
_retryableErrors = new WeakMap(), | ||
_retyableConditions = new WeakMap(), | ||
_a)(); | ||
} | ||
} | ||
@@ -96,2 +138,6 @@ class Retry { | ||
let previousError = null; | ||
Retry.localAsyncStorage.enterWith({ | ||
attempt: 1, | ||
attemptsLeft: maxRetries + 1, | ||
}); | ||
do { | ||
@@ -110,4 +156,6 @@ try { | ||
if (typeof onFailedAttempt === 'function') { | ||
onFailedAttempt(attempts + 1, result, previousError); | ||
onFailedAttempt(attempts + 1, maxRetries - attempts, result, previousError); | ||
} | ||
Retry.localAsyncStorage.getStore().attempt++; | ||
Retry.localAsyncStorage.getStore().attemptsLeft--; | ||
attemptsLeft = attempts++ < maxRetries; | ||
@@ -132,4 +180,38 @@ shouldRetry = shouldRetry && attemptsLeft; | ||
} | ||
/** | ||
* @returns The number of the current attempt. | ||
* | ||
* The method is only invocateable inside Retryable operation | ||
*/ | ||
static getAttempt() { | ||
const store = Retry.localAsyncStorage.getStore(); | ||
if (!store) { | ||
throw new Error('getAttempt can only be called in a retryable operation'); | ||
} | ||
return store.attempt; | ||
} | ||
/** | ||
* @returns The number of left attempts including the current attempt. | ||
* * | ||
* The method is only invocateable inside Retryable operation | ||
*/ | ||
static getAttemptLeft() { | ||
const store = Retry.localAsyncStorage.getStore(); | ||
if (!store) { | ||
throw new Error('getAttemptLeft can only be called in a retryable operation'); | ||
} | ||
return store.attemptsLeft; | ||
} | ||
/** | ||
* @returns true if the current attempt is the last one. | ||
* | ||
* The method is only invocateable inside Retryable operation | ||
*/ | ||
static isLastAttempt() { | ||
const attemptsLeft = Retry.getAttemptLeft(); | ||
return attemptsLeft <= 1; | ||
} | ||
} | ||
exports.Retry = Retry; | ||
Retry.localAsyncStorage = new async_hooks_1.AsyncLocalStorage(); | ||
/** | ||
@@ -136,0 +218,0 @@ * List of built-in delays |
{ | ||
"name": "@yveskaufmann/retry", | ||
"version": "1.1.0", | ||
"version": "1.1.1", | ||
"description": "Utility for retrying promise based operation on certain situations.", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -141,7 +141,9 @@ # @yveskaufmann/retry - retry-utility | ||
/** | ||
/** | ||
* Will be invoked after each failed attempt. | ||
* An atempt is to be considered failed, if the `retryWhen` classify a returned error/return-values as retryable. | ||
* @param attempt The number of the attempt | ||
* @param attempt The number of the attempt. | ||
* @param attemptsLeft The number of attempts left. | ||
* @param result The returned value from the retryable operation, that is considered be a reason to perform a retry | ||
@@ -151,3 +153,3 @@ * @param err The cause of the failed attempt | ||
*/ | ||
onFailedAttempt?: (attempt: number, result: T, err: Error) => void; | ||
onFailedAttempt?: (attempt: number, attemptsLeft: number, result: T, err: Error) => void; | ||
} | ||
@@ -154,0 +156,0 @@ ``` |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
55682
21
482
319
1