Skip to content

Commit

Permalink
Merge pull request #54 from spaceagetv/refactor/set-retry-default
Browse files Browse the repository at this point in the history
Refactor: setRetryOptions() + 'Promise was collected'
  • Loading branch information
jjeff authored Nov 16, 2024
2 parents ef2c034 + ed8a92c commit bfd574b
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 12 deletions.
52 changes: 51 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,20 @@ For example, wait for a MenuItem to be enabled... or be visible.. etc</p></dd>
<dd><p>Add a timeout to any helper function from this library which returns a Promise.</p></dd>
<dt><a href="#retry">retry(fn, [options])</a> ⇒ <code>Promise.&lt;T&gt;</code></dt>
<dd><p>Retries a function until it returns without throwing an error containing a specific message.</p></dd>
<dt><a href="#setRetryOptions">setRetryOptions(options)</a> ⇒</dt>
<dd><p>Sets the default retry() options. These options will be used for all subsequent calls to retry() unless overridden.
You can reset the defaults at any time by calling resetRetryDefaults().</p></dd>
<dt><a href="#getRetryOptions">getRetryOptions()</a> ⇒</dt>
<dd><p>Gets the current default retry options.</p></dd>
<dt><a href="#resetRetryOptions">resetRetryOptions()</a></dt>
<dd><p>Resets the retry options to their default values.</p>
<p>The default values are:</p>
<ul>
<li>retries: 5</li>
<li>intervalMs: 200</li>
<li>timeoutMs: 5000</li>
<li>errorMatch: 'context or browser has been closed'</li>
</ul></dd>
<dt><a href="#errToString">errToString(err)</a> ⇒</dt>
<dd><p>Converts an unknown error to a string representation.</p>
<p>This function handles different types of errors and attempts to convert them
Expand Down Expand Up @@ -758,8 +772,44 @@ For example, wait for a MenuItem to be enabled... or be visible.. etc</p>
| [options.retries] | <code>number</code> | <code>5</code> | <p>The number of retry attempts.</p> |
| [options.intervalMs] | <code>number</code> | <code>200</code> | <p>The delay between each retry attempt in milliseconds.</p> |
| [options.timeoutMs] | <code>number</code> | <code>5000</code> | <p>The maximum time to wait before giving up in milliseconds.</p> |
| [options.errorMatch] | <code>string</code> \| <code>RegExp</code> | <code>&quot;&#x27;context or browser has been closed&#x27;&quot;</code> | <p>The error message or pattern to match against.</p> |
| [options.errorMatch] | <code>string</code> \| <code>RegExp</code> | <code>&quot;[&#x27;context or browser has been closed&#x27;, &#x27;Promise was collected&#x27;]&quot;</code> | <p>The error message or pattern to match against.</p> |

<a name="setRetryOptions"></a>

## setRetryOptions(options) ⇒
<p>Sets the default retry() options. These options will be used for all subsequent calls to retry() unless overridden.
You can reset the defaults at any time by calling resetRetryDefaults().</p>

**Kind**: global function
**Returns**: <p>The updated retry options.</p>
**Category**: Utilities

| Param | Description |
| --- | --- |
| options | <p>A partial object containing the retry options to be set.</p> |

<a name="getRetryOptions"></a>

## getRetryOptions() ⇒
<p>Gets the current default retry options.</p>

**Kind**: global function
**Returns**: <p>The current retry options.</p>
**Category**: Utilities
<a name="resetRetryOptions"></a>

## resetRetryOptions()
<p>Resets the retry options to their default values.</p>
<p>The default values are:</p>
<ul>
<li>retries: 5</li>
<li>intervalMs: 200</li>
<li>timeoutMs: 5000</li>
<li>errorMatch: 'context or browser has been closed'</li>
</ul>

**Kind**: global function
**Category**: Utilities
<a name="errToString"></a>

## errToString(err) ⇒
Expand Down
78 changes: 67 additions & 11 deletions src/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,12 @@ export type RetryOptions = {
intervalMs?: number
/** The maximum time to wait before giving up (in milliseconds) */
timeoutMs?: number
/** The error message or pattern to match against. Errors that don't match will throw immediately. */
errorMatch?: string | RegExp
/**
* The error message or pattern to match against. Errors that don't match will throw immediately.
* If a string or array of strings, the error will throw if it does not contain (one of) the passed string(s).
* If a RegExp, the error will throw if it does not match the pattern.
*/
errorMatch?: string | string[] | RegExp
}

/**
Expand All @@ -99,19 +103,17 @@ export type RetryOptions = {
* @param {number} [options.retries=5] The number of retry attempts.
* @param {number} [options.intervalMs=200] The delay between each retry attempt in milliseconds.
* @param {number} [options.timeoutMs=5000] The maximum time to wait before giving up in milliseconds.
* @param {string|RegExp} [options.errorMatch='context or browser has been closed'] The error message or pattern to match against.
* @param {string|RegExp} [options.errorMatch=['context or browser has been closed', 'Promise was collected']] The error message or pattern to match against.
* @returns {Promise<T>} A promise that resolves with the result of the function or rejects with an error or timeout message.
*/
export async function retry<T>(
fn: () => Promise<T> | T,
options: RetryOptions = {}
): Promise<T> {
const {
retries = 10,
intervalMs = 200,
timeoutMs = 5000,
errorMatch = 'context or browser has been closed',
} = options
const { retries, intervalMs, timeoutMs, errorMatch } = {
...getRetryOptions(),
...options,
}
let counter = 0
const startTime = Date.now()

Expand All @@ -122,8 +124,13 @@ export async function retry<T>(
} catch (err) {
const errString = errToString(err)
if (
(typeof errorMatch === 'string' && !errString.includes(errorMatch)) ||
(errorMatch instanceof RegExp && !errorMatch.test(errString))
(typeof errorMatch === 'string' &&
!errString.toLowerCase().includes(errorMatch.toLowerCase())) ||
(errorMatch instanceof RegExp && !errorMatch.test(errString)) ||
(Array.isArray(errorMatch) &&
!errorMatch.some((match) =>
errString.toLowerCase().includes(match.toLowerCase())
))
) {
throw err
}
Expand All @@ -138,6 +145,55 @@ export async function retry<T>(
}
}

const retryDefaults: RetryOptions = {
retries: 5,
intervalMs: 200,
timeoutMs: 5000,
errorMatch: ['context or browser has been closed', 'Promise was collected'],
}

const currentRetryOptions: RetryOptions = { ...retryDefaults }

/**
* Sets the default retry() options. These options will be used for all subsequent calls to retry() unless overridden.
* You can reset the defaults at any time by calling resetRetryOptions().
*
* @category Utilities
*
* @param options - A partial object containing the retry options to be set.
* @returns The updated retry options.
*/
export function setRetryOptions(options: Partial<RetryOptions>): RetryOptions {
Object.assign(currentRetryOptions, options)
return retryDefaults
}

/**
* Gets the current default retry options.
*
* @category Utilities
*
* @returns The current retry options.
*/
export function getRetryOptions(): RetryOptions {
return { ...currentRetryOptions }
}

/**
* Resets the retry options to their default values.
*
* The default values are:
* - retries: 5
* - intervalMs: 200
* - timeoutMs: 5000
* - errorMatch: 'context or browser has been closed'
*
* @category Utilities
*/
export function resetRetryOptions(): void {
Object.assign(currentRetryOptions, retryDefaults)
}

/**
* Converts an unknown error to a string representation.
*
Expand Down

0 comments on commit bfd574b

Please sign in to comment.