From 128ecb6b7c252789906300b29b0f98dd874b27cd Mon Sep 17 00:00:00 2001 From: Torben <8199725+tenjaa@users.noreply.github.com> Date: Fri, 4 Oct 2024 16:09:25 +0200 Subject: [PATCH] fix: handle 429 status code when being throttled (#740) --- src/index.ts | 2 +- test/retry.test.ts | 22 ++++++++++++++-------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/index.ts b/src/index.ts index 95b72bb0..1b540160 100644 --- a/src/index.ts +++ b/src/index.ts @@ -121,7 +121,7 @@ export function throttling(octokit: Octokit, octokitOptions: OctokitOptions) { const shouldRetryGraphQL = pathname.startsWith("/graphql") && error.status !== 401; - if (!(shouldRetryGraphQL || error.status === 403)) { + if (!(shouldRetryGraphQL || error.status === 403 || error.status === 429)) { return; } diff --git a/test/retry.test.ts b/test/retry.test.ts index 60938a5f..d8f0a221 100644 --- a/test/retry.test.ts +++ b/test/retry.test.ts @@ -6,11 +6,17 @@ import { throttling } from "../src/index.ts"; import type { AddressInfo } from "node:net"; import { createServer } from "node:http"; +/** + * According to https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api?apiVersion=2022-11-28 + * both 403 and 429 status codes can be returned when hitting a rate limit. + */ +const restStatusCodes = [403, 429]; + describe( "Retry", function () { - describe("REST", function () { - it("Should retry 'secondary-limit' and succeed", async function () { + describe.each(restStatusCodes)("REST", function (statusCode) { + it(`Should retry 'secondary-limit' and succeed when status ${statusCode}`, async function () { let eventCount = 0; const octokit = new TestOctokit({ throttle: { @@ -34,7 +40,7 @@ describe( request: { responses: [ { - status: 403, + status: statusCode, headers: { "retry-after": "1" }, data: { message: "You have exceeded a secondary rate limit" }, }, @@ -82,12 +88,12 @@ describe( request: { responses: [ { - status: 403, + status: statusCode, headers: { "retry-after": "1" }, data: { message }, }, { - status: 403, + status: statusCode, headers: { "retry-after": "2" }, data: { message }, }, @@ -131,7 +137,7 @@ describe( .end(JSON.stringify({ message: "Success!" })); } else { res - .writeHead(403, { + .writeHead(statusCode, { "Content-Type": "application/json", "retry-after": "1", }) @@ -177,7 +183,7 @@ describe( } }); - it("Should retry 'rate-limit' and succeed", async function () { + it(`Should retry 'rate-limit' with status code ${statusCode} and succeed`, async function () { let eventCount = 0; const octokit = new TestOctokit({ throttle: { @@ -199,7 +205,7 @@ describe( request: { responses: [ { - status: 403, + status: statusCode, headers: { "x-ratelimit-remaining": "0", "x-ratelimit-reset": "123",