Skip to content

Commit 02b6807

Browse files
committed
retryOnError
1 parent 813d671 commit 02b6807

File tree

2 files changed

+58
-1
lines changed

2 files changed

+58
-1
lines changed

retry.ts

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import {
2+
RetryError,
3+
RetryOptions,
4+
} from "https://deno.land/[email protected]/async/retry.ts";
5+
6+
export const defaultRetryOptions = {
7+
multiplier: 2,
8+
maxTimeout: 60000,
9+
maxAttempts: 5,
10+
minTimeout: 1000,
11+
};
12+
export async function retry<T>(
13+
fn: (() => Promise<T>) | (() => T),
14+
opts?: RetryOptions & {
15+
retryOnError?:
16+
| ((error: any) => Promise<boolean>)
17+
| ((error: any) => boolean);
18+
},
19+
) {
20+
const retryOnError = opts?.retryOnError ?? (() => true);
21+
const options: Required<RetryOptions> = {
22+
...defaultRetryOptions,
23+
...opts,
24+
};
25+
26+
if (options.maxTimeout >= 0 && options.minTimeout > options.maxTimeout) {
27+
throw new RangeError("minTimeout is greater than maxTimeout");
28+
}
29+
30+
let timeout = options.minTimeout;
31+
let error: unknown;
32+
33+
for (let i = 0; i < options.maxAttempts; i++) {
34+
try {
35+
return await fn();
36+
} catch (err) {
37+
if (!retryOnError(err)) {
38+
throw err;
39+
}
40+
41+
await new Promise((r) => setTimeout(r, timeout));
42+
timeout *= options.multiplier;
43+
timeout = Math.max(timeout, options.minTimeout);
44+
if (options.maxTimeout >= 0) {
45+
timeout = Math.min(timeout, options.maxTimeout);
46+
}
47+
error = err;
48+
}
49+
}
50+
51+
throw new RetryError(error, options.maxAttempts);
52+
}

xmake.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { join, resolve } from "https://deno.land/[email protected]/path/mod.ts";
55
import { assertEquals } from "asserts";
66
import { dirname } from "https://deno.land/x/[email protected]/mod.ts";
77
import parse from "npm:@masx200/[email protected]";
8-
import { retry } from "https://deno.land/[email protected]/async/retry.ts";
8+
import { retry } from "./retry.ts";
99

1010
async function* findFilesRecursive(
1111
path: string,
@@ -40,6 +40,11 @@ async function RunXmake(file: string, toolchain: string, sdk: string) {
4040
await RunXmakeConfig(file, toolchain, sdk);
4141
await retry(RunXmakeBuild.bind(null, file), {
4242
maxAttempts: os === "windows" ? 10 : 1,
43+
retryOnError: (e) => {
44+
return Boolean(
45+
e?.stdout?.match(/error:.*cannot open file:.*Unknown/g),
46+
);
47+
},
4348
});
4449
await RunXmakeTest(file);
4550
}

0 commit comments

Comments
 (0)