Unverified Commit 9328a57e authored by Anurag Hazra's avatar Anurag Hazra Committed by GitHub
Browse files

Merge pull request #58 from anuraghazra/fix-ratelimit

fix: increase github rate limit with multiple PATs

- special thanks to @filiptronicek @ApurvShah007 @garvit-joshi for helping out :D
parents 2efb399f 429d65a5
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -18,7 +18,9 @@ module.exports = async (req, res) => {
  } = req.query;
  let stats;

  res.setHeader("Cache-Control", "public, max-age=1800");
  res.setHeader("Content-Type", "image/svg+xml");

  try {
    stats = await fetchStats(username);
  } catch (err) {
+2 −0
Original line number Diff line number Diff line
@@ -14,6 +14,8 @@ module.exports = async (req, res) => {
  } = req.query;

  let repoData;
  
  res.setHeader("Cache-Control", "public, max-age=1800");
  res.setHeader("Content-Type", "image/svg+xml");

  try {
+18 −11
Original line number Diff line number Diff line
const { request } = require("./utils");
const retryer = require("./retryer");

async function fetchRepo(username, reponame) {
  if (!username || !reponame) {
    throw new Error("Invalid username or reponame");
  }

  const res = await request({
const fetcher = (variables, token) => {
  return request(
    {
      query: `
      fragment RepoInfo on Repository {
        name
@@ -33,11 +31,20 @@ async function fetchRepo(username, reponame) {
        }
      }
    `,
    variables: {
      login: username,
      repo: reponame,
      variables,
    },
  });
    {
      Authorization: `bearer ${token}`,
    }
  );
};

async function fetchRepo(username, reponame) {
  if (!username || !reponame) {
    throw new Error("Invalid username or reponame");
  }

  let res = await retryer(fetcher, { login: username, repo: reponame });

  const data = res.data.data;

+25 −15
Original line number Diff line number Diff line
const { request } = require("./utils");
const retryer = require("./retryer");
const calculateRank = require("./calculateRank");
require("dotenv").config();

async function fetchStats(username) {
  if (!username) throw Error("Invalid username");

  const res = await request({
const fetcher = (variables, token) => {
  return request(
    {
      query: `
      query userInfo($login: String!) {
        user(login: $login) {
          name
          login
          repositoriesContributedTo(first: 100, contributionTypes: [COMMIT, ISSUE, PULL_REQUEST, REPOSITORY]) {
            totalCount
          }
          contributionsCollection {
            totalCommitContributions
          }
          pullRequests(first: 100) {
          repositoriesContributedTo(first: 1, contributionTypes: [COMMIT, ISSUE, PULL_REQUEST, REPOSITORY]) {
            totalCount
          }
          pullRequests(first: 1) {
            totalCount
          }
          issues(first: 100) {
          issues(first: 1) {
            totalCount
          }
          followers {
@@ -37,8 +37,16 @@ async function fetchStats(username) {
        }
      }
      `,
    variables: { login: username },
  });
      variables,
    },
    {
      Authorization: `bearer ${token}`,
    }
  );
};

async function fetchStats(username) {
  if (!username) throw Error("Invalid username");

  const stats = {
    name: "",
@@ -47,12 +55,14 @@ async function fetchStats(username) {
    totalIssues: 0,
    totalStars: 0,
    contributedTo: 0,
    rank: "C",
    rank: { level: "C", score: 0 },
  };

  let res = await retryer(fetcher, { login: username });

  if (res.data.errors) {
    console.log(res.data.errors);
    throw Error("Could not fetch user");
    throw Error(res.data.errors[0].message || "Could not fetch user");
  }

  const user = res.data.data.user;

src/retryer.js

0 → 100644
+43 −0
Original line number Diff line number Diff line
const retryer = async (fetcher, variables, retries = 0) => {
  if (retries > 7) {
    throw new Error("Maximum retries exceeded");
  }
  try {
    console.log(`Trying PAT_${retries + 1}`);

    // try to fetch with the first token since RETRIES is 0 index i'm adding +1
    let response = await fetcher(
      variables,
      process.env[`PAT_${retries + 1}`],
      retries
    );

    // prettier-ignore
    const isRateExceeded = response.data.errors && response.data.errors[0].type === "RATE_LIMITED";

    // if rate limit is hit increase the RETRIES and recursively call the retryer
    // with username, and current RETRIES
    if (isRateExceeded) {
      console.log(`PAT_${retries + 1} Failed`);
      retries++;
      // directly return from the function
      return retryer(fetcher, variables, retries);
    }

    // finally return the response
    return response;
  } catch (err) {
    // prettier-ignore
    // also checking for bad credentials if any tokens gets invalidated
    const isBadCredential = err.response.data && err.response.data.message === "Bad credentials";

    if (isBadCredential) {
      console.log(`PAT_${retries + 1} Failed`);
      retries++;
      // directly return from the function
      return retryer(fetcher, variables, retries);
    }
  }
};

module.exports = retryer;
Loading