Skip to content

Commit

Permalink
feat!: add more functionality to retryDelay
Browse files Browse the repository at this point in the history
  • Loading branch information
jd1378 committed May 23, 2023
1 parent d0a5e74 commit 9cfecb8
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 8 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
# Changelog

## v7.0.0

- break `retryDelay` function signature to add error that caused retry and an
abort controller to cancel retrying.

## v6.2.2

- update `retryDelay` signature for more consistency with other stuff like interceptors.
- update `retryDelay` signature for more consistency with other stuff like
interceptors.

## v6.2.1

Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ This library offers a fetch wrapper that can:
- accept a `timeout` option and abort when timeout is reached
- accept a `retry` option and retry the request when it throws
- accept a `retryDelay` option to wait before retrying. it can be a function.
further retries can be cancelled as well!
- add `Accept` header with value `application/json, text/plain, */*` if not
already set by you
- set global headers when creating the wrapper
Expand All @@ -21,7 +22,7 @@ This library offers a fetch wrapper that can:
you can import `wrapFetch` from `mod.ts` file.

```ts
export { wrapFetch } from "https://deno.land/x/fetch_goody@v6.2.2/mod.ts";
export { wrapFetch } from "https://deno.land/x/fetch_goody@v7.0.0/mod.ts";
```

### wrapFetch
Expand Down
12 changes: 9 additions & 3 deletions extended_request_init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,15 @@ interface RequestInitDiff {
}

export type RetryDelayFunction = (
/** current attempt (1 = it is going to retry for the first time and so on) */
attempt: number,
init: ExtendedRequest,
options: {
/** current attempt (1 = it is going to retry for the first time and so on) */
attempt: number;
request: ExtendedRequest;
/** the error causing retry */
error: unknown;
/** calling this AbortController's abort will stop retrying the request */
abortController: AbortController;
},
) => number;

export type Interceptors = {
Expand Down
9 changes: 8 additions & 1 deletion fetch_wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -288,9 +288,16 @@ export function wrapFetch(options?: WrapFetchOptions) {
retryDelay,
);
if (typeof delayVal === "function") {
const retryAbortController = new AbortController();
await utils.delay(
delayVal(attempt, interceptedInit as ExtendedRequest),
delayVal({
attempt,
request: interceptedInit as ExtendedRequest,
error: e,
abortController: retryAbortController,
}),
);
retryAbortController.signal.throwIfAborted();
} else {
await utils.delay(delayVal);
}
Expand Down
45 changes: 43 additions & 2 deletions fetch_wrapper_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -765,9 +765,9 @@ Deno.test("Retry option", {
},
},
retry: 3,
retryDelay: (attempt, init) => {
retryDelay: ({ attempt, request }) => {
lastAttempt = attempt;
lastInit = init;
lastInit = request;
assertStrictEquals(count, attempt);
return 0;
},
Expand Down Expand Up @@ -797,4 +797,45 @@ Deno.test("Retry option", {
);
},
);

await t.step(
"retryDelay can be aborted",
async () => {
const wrappedFetch = wrapFetch();

let count = 0;

try {
await wrappedFetch(serverOneUrl + "/count", {
body: "foo",
interceptors: {
request() {
count++;
throw new Error("arbitrary");
},
},
retry: 10,
retryDelay: ({ abortController }) => {
if (count >= 2) {
// means if we already failed 2 times, do not retry anymore
abortController.abort();
}
return 0;
},
});
} catch {
}

assert(
count < 10,
"count (" + count + ") is bigger than retry (10)",
);

assertStrictEquals(
count,
2,
"retry count is " + count + " but should be " + 2,
);
},
);
});

0 comments on commit 9cfecb8

Please sign in to comment.