@atolis-hq/wake 0.3.74 → 0.3.75
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const defaultMaximumGitHubResponseBytes = 8 * 1024 * 1024;
|
|
2
|
+
const defaultGitHubRequestTimeoutMs = 30_000;
|
|
2
3
|
export class GitHubResponseTooLargeError extends Error {
|
|
3
4
|
maximumBytes;
|
|
4
5
|
observedBytes;
|
|
@@ -9,9 +10,39 @@ export class GitHubResponseTooLargeError extends Error {
|
|
|
9
10
|
this.name = 'GitHubResponseTooLargeError';
|
|
10
11
|
}
|
|
11
12
|
}
|
|
12
|
-
|
|
13
|
+
// Neither Octokit nor the underlying fetch implementation bounds how long a
|
|
14
|
+
// single request may hang: a connection that never responds (rather than
|
|
15
|
+
// returning a clean error status) blocks forever. Every caller of the GitHub
|
|
16
|
+
// client boundary — reads and mutations alike — currently awaits that call
|
|
17
|
+
// inline within the runner's single serialized tick, so one hung request
|
|
18
|
+
// stalls Advancement for every other, unrelated work item too.
|
|
19
|
+
export class GitHubRequestTimeoutError extends Error {
|
|
20
|
+
timeoutMs;
|
|
21
|
+
constructor(timeoutMs) {
|
|
22
|
+
super(`GitHub request did not complete within ${timeoutMs}ms`);
|
|
23
|
+
this.timeoutMs = timeoutMs;
|
|
24
|
+
this.name = 'GitHubRequestTimeoutError';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export function createBoundedGitHubFetch(baseFetch = globalThis.fetch, maximumResponseBytes = defaultMaximumGitHubResponseBytes, timeoutMs = defaultGitHubRequestTimeoutMs) {
|
|
13
28
|
return async (input, init) => {
|
|
14
|
-
const
|
|
29
|
+
const timeoutController = new AbortController();
|
|
30
|
+
const timer = setTimeout(() => timeoutController.abort(), timeoutMs);
|
|
31
|
+
const signal = init?.signal
|
|
32
|
+
? AbortSignal.any([init.signal, timeoutController.signal])
|
|
33
|
+
: timeoutController.signal;
|
|
34
|
+
let response;
|
|
35
|
+
try {
|
|
36
|
+
response = await baseFetch(input, { ...init, signal });
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
if (timeoutController.signal.aborted)
|
|
40
|
+
throw new GitHubRequestTimeoutError(timeoutMs);
|
|
41
|
+
throw error;
|
|
42
|
+
}
|
|
43
|
+
finally {
|
|
44
|
+
clearTimeout(timer);
|
|
45
|
+
}
|
|
15
46
|
const declaredBytes = contentLength(response);
|
|
16
47
|
if (declaredBytes !== undefined && declaredBytes > maximumResponseBytes) {
|
|
17
48
|
await response.body?.cancel();
|