From 604cd3633440ca132910122586090b682ad8f6a5 Mon Sep 17 00:00:00 2001 From: Harvmaster Date: Thu, 6 Aug 2026 10:06:04 +0000 Subject: [PATCH] Improve validation code. Add throws tsdocs to validateOptions --- source/exponential-backoff.ts | 59 ++++++++++++++++++----------------- source/misc.ts | 16 ++++++++++ 2 files changed, 46 insertions(+), 29 deletions(-) create mode 100644 source/misc.ts diff --git a/source/exponential-backoff.ts b/source/exponential-backoff.ts index 68726ae..59fe07e 100644 --- a/source/exponential-backoff.ts +++ b/source/exponential-backoff.ts @@ -1,11 +1,12 @@ import { ExponentialBackoffStoppedRetriesError, ExponentialBackoffMaxRetriesHitError, - ExponentialBackoffInvalidInfiniteIntegerError, ExponentialBackoffNonIntegerError, ExponentialBackoffNumberTooSmallError, ExponentialBackoffNumberOutOfBoundsError, + ExponentialBackoffNumberNotFiniteError, } from './errors.ts'; +import { isWithinBounds } from './misc.ts'; /** * Exponential backoff is a technique used to retry a function after a delay. @@ -110,60 +111,60 @@ export class ExponentialBackoff { * * @param options - The options to validate * - * @throws An error if the options are invalid + * @throws {@link ExponentialBackoffNumberNotFiniteError} if a provided option is not a finite number + * @throws {@link ExponentialBackoffNonIntegerError} if a provided option is not an integer + * @throws {@link ExponentialBackoffNumberOutOfBoundsError} if a provided option is out of bounds + * @throws {@link ExponentialBackoffNumberTooSmallError} if a provided option is too small */ public static validateOptions(options: ExponentialBackoffOptions): void { /** Validate the value is finite, throwing an {@link ExponentialBackoffInvalidInfiniteIntegerError} if the value is infinite */ - const isFinite = (key: string, value: number): void => { + const assertIsFinite = (key: string, value: number): void => { if (!Number.isFinite(value)) { - throw new ExponentialBackoffInvalidInfiniteIntegerError(key); + throw new ExponentialBackoffNumberNotFiniteError(key, value); } }; /** Validate the value is an integer, throwing a {@link ExponentialBackoffNonIntegerError} if it is not an integer */ - const isInteger = (key: string, value: number): void => { + const assertIsInteger = (key: string, value: number): void => { if (!Number.isInteger(value)) { - throw new ExponentialBackoffNonIntegerError(key); + throw new ExponentialBackoffNonIntegerError(key, value); } }; - /** Validate the value is within the bounds, throwing a {@link ExponentialBackoffNumberOutOfBoundsError} if it is not within the bounds */ - const isWithinBounds = (key: string, value: number, min: number, max?: number): void => { - // If both the min and max are defined, validate the value, throwing a number out of bounds error if it is not within the bounds - if (min !== undefined && max !== undefined) { - if (value < min || value > max) { - throw new ExponentialBackoffNumberOutOfBoundsError(key, value, min, max); - } - - return; - } - - // If only the min is defined, validate the value, throwing a number too small error if it is less than the min + /** Validate the value is greater than the minimum, throwing a {@link ExponentialBackoffNumberTooSmallError} if it is not */ + const assertIsHigherThan = (key: string, value: number, min: number): void => { if (value < min) { throw new ExponentialBackoffNumberTooSmallError(key, value, min); } }; + /** Validate the value is within the bounds, throwing a {@link ExponentialBackoffNumberOutOfBoundsError} if it is not within the bounds */ + const assertIsWithinBounds = (key: string, value: number, min: number, max: number): void => { + if (!isWithinBounds(value, min, max)) { + throw new ExponentialBackoffNumberOutOfBoundsError(key, value, min, max); + } + }; + // Validate the max delay - isFinite('maxDelay', options.maxDelay); - isWithinBounds('maxDelay', options.maxDelay, 0); + assertIsFinite('maxDelay', options.maxDelay); + assertIsHigherThan('maxDelay', options.maxDelay, 0); // Validate the max attempts - isFinite('maxAttempts', options.maxAttempts); - isInteger('maxAttempts', options.maxAttempts); - isWithinBounds('maxAttempts', options.maxAttempts, 0); + assertIsFinite('maxAttempts', options.maxAttempts); + assertIsInteger('maxAttempts', options.maxAttempts); + assertIsHigherThan('maxAttempts', options.maxAttempts, 0); // Validate the base delay - isFinite('baseDelay', options.baseDelay); - isWithinBounds('baseDelay', options.baseDelay, 0); + assertIsFinite('baseDelay', options.baseDelay); + assertIsHigherThan('baseDelay', options.baseDelay, 0); // Validate the growth rate - isFinite('growthRate', options.growthRate); - isWithinBounds('growthRate', options.growthRate, 0); + assertIsFinite('growthRate', options.growthRate); + assertIsHigherThan('growthRate', options.growthRate, 0); // Validate the jitter - isFinite('jitter', options.jitter); - isWithinBounds('jitter', options.jitter, 0, 1); + assertIsFinite('jitter', options.jitter); + assertIsWithinBounds('jitter', options.jitter, 0, 1); } /** diff --git a/source/misc.ts b/source/misc.ts new file mode 100644 index 0000000..7ac6c43 --- /dev/null +++ b/source/misc.ts @@ -0,0 +1,16 @@ +/** + * Validate the value is within the bounds, returning true if it is within the bounds, false otherwise + * + * @param value - The value to validate + * @param min - The minimum value + * @param max - The maximum value + * + * @returns True if the value is within the bounds, false otherwise + */ +export const isWithinBounds = (value: number, min: number, max: number): boolean => { + if (value < min || value > max) { + return false; + } + + return true; +}; \ No newline at end of file