Commit 429d65a5 authored by anuraghazra's avatar anuraghazra
Browse files

refactor: refactored retryer logic & handled invalid tokens

parent 3d8dea90
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -18,7 +18,7 @@ module.exports = async (req, res) => {
  } = req.query;
  let stats;

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

  try {
+1 −1
Original line number Diff line number Diff line
@@ -15,7 +15,7 @@ module.exports = async (req, res) => {

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

  try {
+13 −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 {
@@ -34,15 +31,20 @@ async function fetchRepo(username, reponame) {
        }
      }
    `,
      variables: {
        login: username,
        repo: reponame,
      },
      variables,
    },
    {
      Authorization: `bearer ${process.env.PAT_1}`,
      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;

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

// creating a fetcher function to reduce duplication
const fetcher = (username, token) => {
const fetcher = (variables, token) => {
  return request(
    {
      query: `
@@ -37,43 +37,15 @@ const fetcher = (username, token) => {
        }
      }
      `,
      variables: { login: username },
      variables,
    },
    {
      // set the token
      Authorization: `bearer ${token}`,
    }
  );
};

async function retryer(username, RETRIES) {
  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(username, process.env[`PAT_${RETRIES + 1}`]);

    // if rate limit is hit increase the RETRIES and recursively call the retryer
    // with username, and current RETRIES
    if (
      response.data.errors &&
      response.data.errors[0].type === "RATE_LIMITED"
    ) {
      console.log(`PAT_${RETRIES} Failed`);
      RETRIES++;
      // directly return from the function
      return await retryer(username, RETRIES);
    }

    // finally return the response
    return response;
  } catch (err) {
    console.log(err);
  }
}

async function fetchStats(username) {
  let RETRIES = 0;
  if (!username) throw Error("Invalid username");

  const stats = {
@@ -86,7 +58,7 @@ async function fetchStats(username) {
    rank: { level: "C", score: 0 },
  };

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

  if (res.data.errors) {
    console.log(res.data.errors);

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