This repository was archived by the owner on May 11, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.ts
More file actions
123 lines (102 loc) 路 3.25 KB
/
Copy pathindex.ts
File metadata and controls
123 lines (102 loc) 路 3.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
type Options<T> = {
retry?: boolean;
retries?: number;
retryDelay?: number;
jitter?: number;
fallback?: (() => Promise<T>) | Array<() => Promise<T>>;
timeout?: boolean;
timeoutAfter?: number;
onTimeout?: () => void;
onRetry?: (retryNumber: number) => void;
onSuccess?: (result: T) => void;
onError?: (error: Error | Error[]) => void;
}
export async function tryvial<T>(
fn: () => Promise<T>,
options?: Options<T>
): Promise<T | undefined> {
const {
retry = false,
retries = 2,
retryDelay = 0,
jitter = 0,
fallback,
timeout = false,
timeoutAfter = 10000,
onTimeout,
onRetry,
onSuccess,
onError,
} = options || {};
let retriesLeft = retries;
while (true) {
try {
let result: T
if (timeout) {
result = await Promise.race([
fn(),
new Promise<T>((_, reject) => {
setTimeout(() => {
reject(new Error());
if (onTimeout) {
onTimeout();
}
}, timeoutAfter)
})
])
} else {
result = await fn();
}
if (onSuccess) {
onSuccess(result as T);
}
return result as T;
} catch (error) {
retriesLeft--;
if (retriesLeft >= 0 && retry) {
if (onRetry) {
onRetry(retries - retriesLeft);
}
const waitTime = Math.max(retryDelay,(Math.floor(Math.random() * jitter) + retryDelay));
await new Promise((resolve) => setTimeout(resolve, waitTime));
continue;
}
if (onError) {
onError(error as Error);
}
if (fallback) {
if (Array.isArray(fallback)) {
const errorArray: Error[] = []
for (const fallbackFn of fallback) {
try {
const fallbackResult = await fallbackFn();
if (onSuccess) {
onSuccess(fallbackResult);
}
return fallbackResult;
} catch (fallbackError) {
errorArray.push(fallbackError as Error);
}
}
if (onError) {
onError(errorArray);
}
} else {
try {
const fallbackResult = await fallback();
if (onSuccess) {
onSuccess(fallbackResult);
}
return fallbackResult;
} catch (fallbackError) {
if (onError) {
onError(fallbackError as Error)
}
}
}
}
return undefined
}
}
}
export default tryvial