Skip to content

Commit 493eee1

Browse files
committed
Handle GitHub API rate limits in script
1 parent c8d5fc6 commit 493eee1

File tree

1 file changed

+28
-1
lines changed

1 file changed

+28
-1
lines changed

docs/scripts/update-contributors.js

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import fs from "node:fs/promises";
2+
import timers from "node:timers/promises";
23
import { URL } from "node:url";
34

45
const MAINTAINERS = {
@@ -227,9 +228,33 @@ async function fetchUserInfo(username) {
227228
"X-GitHub-Api-Version": "2022-11-28",
228229
},
229230
});
231+
230232
if (!res.ok) {
233+
const retryAfter = res.headers.get("retry-after"); // seconds
234+
const ratelimitRemaining = res.headers.get("x-ratelimit-remaining"); // quantity of requests remaining
235+
const ratelimitReset = res.headers.get("x-ratelimit-reset"); // UTC epoch seconds
236+
237+
if (retryAfter || ratelimitRemaining === "0" || ratelimitReset) {
238+
// See https://docs.github.com/en/rest/using-the-rest-api/best-practices-for-using-the-rest-api?apiVersion=2022-11-28#handle-rate-limit-errors-appropriately
239+
console.warn("Rate limited by GitHub API");
240+
241+
let timeoutInMilliseconds = 60 * 1000; // default to 1 minute
242+
if (retryAfter) {
243+
timeoutInMilliseconds = retryAfter * 1000;
244+
} else if (ratelimitRemaining === "0" && ratelimitReset) {
245+
timeoutInMilliseconds = ratelimitReset * 1000 - Date.now();
246+
}
247+
248+
console.warn(`Waiting for ${timeoutInMilliseconds / 1000} seconds...`);
249+
250+
await timers.setTimeout(timeoutInMilliseconds);
251+
252+
return await fetchUserInfo(username);
253+
}
254+
231255
throw new UserFetchError(`${res.url} responded with ${res.status}`, res);
232256
}
257+
233258
return await res.json();
234259
}
235260

@@ -282,4 +307,6 @@ async function main() {
282307
}
283308
}
284309

285-
main();
310+
if (import.meta.main) {
311+
main();
312+
}

0 commit comments

Comments
 (0)