fix: react on both type and message-based rate-limit signals (#4440)
Co-authored-by: Alexandr <qwerty541zxc@gmail.com>
This commit is contained in:
committed by
martin-mfg
co-authored by
Alexandr
parent
cd40532db7
commit
ab2b0f4c97
@@ -25,12 +25,14 @@ const retryer = async (fetcher, variables, retries = 0) => {
|
||||
if (!RETRIES) {
|
||||
throw new CustomError("No GitHub API tokens found", CustomError.NO_TOKENS);
|
||||
}
|
||||
|
||||
if (retries > RETRIES) {
|
||||
throw new CustomError(
|
||||
"Downtime due to GitHub API rate limiting",
|
||||
CustomError.MAX_RETRY,
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
// try to fetch with the first token since RETRIES is 0 index i'm adding +1
|
||||
let response = await fetcher(
|
||||
@@ -39,12 +41,16 @@ const retryer = async (fetcher, variables, retries = 0) => {
|
||||
retries,
|
||||
);
|
||||
|
||||
// prettier-ignore
|
||||
const isRateExceeded = response.data.errors && response.data.errors[0].type === "RATE_LIMITED";
|
||||
// react on both type and message-based rate-limit signals.
|
||||
const errors = response?.data?.errors;
|
||||
const errorType = errors?.[0]?.type;
|
||||
const errorMsg = errors?.[0]?.message || "";
|
||||
const isRateLimited =
|
||||
(errors && errorType === "RATE_LIMITED") || /rate limit/i.test(errorMsg);
|
||||
|
||||
// if rate limit is hit increase the RETRIES and recursively call the retryer
|
||||
// with username, and current RETRIES
|
||||
if (isRateExceeded) {
|
||||
if (isRateLimited) {
|
||||
logger.log(`PAT_${retries + 1} Failed due to rate limiting`);
|
||||
retries++;
|
||||
// directly return from the function
|
||||
|
||||
@@ -25,6 +25,27 @@ const fetcherFailOnSecondTry = jest.fn((_vars, _token, retries) => {
|
||||
});
|
||||
});
|
||||
|
||||
const fetcherFailWithMessageBasedRateLimitErr = jest.fn(
|
||||
(_vars, _token, retries) => {
|
||||
return new Promise((res) => {
|
||||
// faking rate limit
|
||||
if (retries < 1) {
|
||||
return res({
|
||||
data: {
|
||||
errors: [
|
||||
{
|
||||
type: "ASDF",
|
||||
message: "API rate limit already exceeded for user ID 11111111",
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
}
|
||||
return res({ data: "ok" });
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
describe("Test Retryer", () => {
|
||||
it("retryer should return value and have zero retries on first try", async () => {
|
||||
let res = await retryer(fetcher, {});
|
||||
@@ -40,6 +61,13 @@ describe("Test Retryer", () => {
|
||||
expect(res).toStrictEqual({ data: "ok" });
|
||||
});
|
||||
|
||||
it("retryer should return value and have 2 retries with message based rate limit error", async () => {
|
||||
let res = await retryer(fetcherFailWithMessageBasedRateLimitErr, {});
|
||||
|
||||
expect(fetcherFailWithMessageBasedRateLimitErr).toBeCalledTimes(2);
|
||||
expect(res).toStrictEqual({ data: "ok" });
|
||||
});
|
||||
|
||||
it("retryer should throw specific error if maximum retries reached", async () => {
|
||||
try {
|
||||
await retryer(fetcherFail, {});
|
||||
|
||||
Reference in New Issue
Block a user