Skip to content

bug: Sync script crashes and aborts entire leaderboard update on single user API failure #101

@Vachhani-Tapan

Description

@Vachhani-Tapan

Describe the Bug

Currently, in scripts/sync-leaderboard.js, the daily synchronization process fetches LeetCode statistics for all registered users using a public API. If the API request fails for even one user (due to a renamed LeetCode ID, a private account issue, temporary rate-limiting, or a network timeout), the script calls process.exit(1) and crashes completely.

This aborts the entire synchronization run, preventing the leaderboard data (overall.json, daily.json, weekly.json, monthly.json) from being generated and updated for all other students.

Affected Code

In scripts/sync-leaderboard.js:

async function fetchData(url) {
  try {
    const res = await axios.get(url);
    return {
      easySolved: res.data.easySolved || 0,
      mediumSolved: res.data.mediumSolved || 0,
      hardSolved: res.data.hardSolved || 0,
    };
  } catch (err) {
    console.error("API failed to respond: ", err.message);
    process.exit(1); // <-- CRITICAL BUG: This terminates the entire script.
  }
}

If fetchData fails, the execution terminates immediately, meaning none of the subsequent users are processed, and no leaderboard files are saved.

Expected Behavior

- The sync script should be fault-tolerant and resilient.

- If a user's API request fails:
      1. The script should retry the request (e.g., 3 times with exponential backoff).
      2. If all retries fail, it should log a warning, skip that specific user, and continue fetching stats for the remaining users in the database.
The leaderboard should update successfully for everyone else.


Proposed Solution
1. Implement Retries in fetchData: Update fetchData to support retry logic with backoff.
2. Graceful Failure Handling: If the fetch fails after all retries, return null instead of calling process.exit(1).
3. Loop Defense: Update the loop in sync-leaderboard.js to check if the returned data is null. If null, log an error message for that user and continue (continue) the loop without inserting them into overallData or throwing a TypeError (when reading easySolved etc.).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions