denoland / denoland/std

[async /retry.ts]add option retryOnError to RetryOptions.

Open
#3,369 3 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
3.6k
Forks
681
PR merge metrics
No merged PRs in 30d

Description

**Is your feature request related to a problem? Please describe.**

https://github.com/denoland/deno_std/blob/a951ed6c029a58b789dbdad54e4348cbfb943400/async/retry.ts#L51

**Describe the solution you'd like**

By passing in the retryOnError function, you can customize whether the error encountered should continue to be retried.

**Describe alternatives you've considered**

```ts
import {
RetryError,
RetryOptions,
} from "https://deno.land/std@0.186.0/async/retry.ts";

export const defaultRetryOptions = {
multiplier: 2,
maxTimeout: 60000,
maxAttempts: 5,
minTimeout: 1000,
};
export async function retry(
fn: (() => Promise) | (() => T),
opts?: RetryOptions & {
retryOnError?:
| ((error: any) => Promise)
| ((error: any) => boolean);
},
) {
const retryOnError = opts?.retryOnError ?? (() => true);
const options: Required = {
...defaultRetryOptions,
...opts,
};

if (options.maxTimeout >= 0 && options.minTimeout > options.maxTimeout) {
throw new RangeError("minTimeout is greater than maxTimeout");
}

let timeout = options.minTimeout;
let error: unknown;

for (let i = 0; i < options.maxAttempts; i++) {
try {
return await fn();
} catch (err) {
if (!await retryOnError(err)) {
throw err;
}

await new Promise((r) => setTimeout(r, timeout));
timeout *= options.multiplier;
timeout = Math.max(timeout, options.minTimeout);
if (options.maxTimeout >= 0) {
timeout = Math.min(timeout, options.maxTimeout);
}
error = err;
}
}

throw new RetryError(error, options.maxAttempts);
}

```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.