1 | import Bottleneck from 'bottleneck/light';
|
2 |
|
3 |
|
4 | async function errorRequest(octokit, state, error, options) {
|
5 | if (!error.request || !error.request.request) {
|
6 |
|
7 | throw error;
|
8 | }
|
9 |
|
10 | if (error.status >= 400 && !state.doNotRetry.includes(error.status)) {
|
11 | const retries = options.request.retries != null ? options.request.retries : state.retries;
|
12 | const retryAfter = Math.pow((options.request.retryCount || 0) + 1, 2);
|
13 | throw octokit.retry.retryRequest(error, retries, retryAfter);
|
14 | }
|
15 |
|
16 | throw error;
|
17 | }
|
18 |
|
19 |
|
20 |
|
21 | async function wrapRequest(state, request, options) {
|
22 | const limiter = new Bottleneck();
|
23 |
|
24 | limiter.on("failed", function (error, info) {
|
25 | const maxRetries = ~~error.request.request.retries;
|
26 | const after = ~~error.request.request.retryAfter;
|
27 | options.request.retryCount = info.retryCount + 1;
|
28 | if (maxRetries > info.retryCount) {
|
29 |
|
30 |
|
31 | return after * state.retryAfterBaseValue;
|
32 | }
|
33 | });
|
34 | return limiter.schedule(request, options);
|
35 | }
|
36 |
|
37 | const VERSION = "3.0.5";
|
38 | function retry(octokit, octokitOptions = {}) {
|
39 | const state = Object.assign({
|
40 | enabled: true,
|
41 | retryAfterBaseValue: 1000,
|
42 | doNotRetry: [400, 401, 403, 404, 422],
|
43 | retries: 3,
|
44 | }, octokitOptions.retry);
|
45 | octokit.retry = {
|
46 | retryRequest: (error, retries, retryAfter) => {
|
47 | error.request.request = Object.assign({}, error.request.request, {
|
48 | retries: retries,
|
49 | retryAfter: retryAfter,
|
50 | });
|
51 | return error;
|
52 | },
|
53 | };
|
54 | if (!state.enabled) {
|
55 | return;
|
56 | }
|
57 | octokit.hook.error("request", errorRequest.bind(null, octokit, state));
|
58 | octokit.hook.wrap("request", wrapRequest.bind(null, state));
|
59 | }
|
60 | retry.VERSION = VERSION;
|
61 |
|
62 | export { VERSION, retry };
|
63 |
|