Description
Multiple server-side fetch() calls lack timeout handling via AbortController. If the LeetCode API wrapper or GitHub API hangs, the request stalls indefinitely with no timeout, no fallback, no recovery path.
Affected Locations
| File |
Line |
Request |
Risk |
scripts/fetch-user-info.js |
25 |
fetch(rawUrl) — GitHub raw data |
Hangs entire user profile request |
scripts/fetch-user-info.js |
53 |
fetch(liveApiUrl) — LeetCode API wrapper |
Hangs entire user profile request |
server.js |
204 |
fetchUserInfo(username) — no timeout passed down |
Cascading timeout failure |
Steps to Reproduce
- Start the server.
- Trigger
/api/user/:username for any user.
- If the LeetCode wrapper API becomes unresponsive,
livePromise (line 53) never resolves/rejects.
- The entire request hangs forever. No timeout mechanism exists.
- Subsequent requests accumulate, consuming server connections.
Expected Behavior
Every outbound fetch() should have an AbortController with a 15-second timeout that cleanly aborts and triggers the existing error/fallback paths.
Actual Behavior
Zero timeout configuration. If a remote API hangs, the server hangs with it.
Suggested Fix
Create a reusable helper in fetch-user-info.js:
async function fetchWithTimeout(url, timeoutMs = 15000) {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
try {
const res = await fetch(url, { signal: controller.signal });
return res;
} finally {
clearTimeout(timeoutId);
}
}
Replace both fetch(rawUrl) and fetch(liveApiUrl) calls with fetchWithTimeout(...).
Affected Files
scripts/fetch-user-info.js (lines 25, 53)
server.js (line 204 — ensure timeout is respected)
Description
Multiple server-side
fetch()calls lack timeout handling viaAbortController. If the LeetCode API wrapper or GitHub API hangs, the request stalls indefinitely with no timeout, no fallback, no recovery path.Affected Locations
scripts/fetch-user-info.jsfetch(rawUrl)— GitHub raw datascripts/fetch-user-info.jsfetch(liveApiUrl)— LeetCode API wrapperserver.jsfetchUserInfo(username)— no timeout passed downSteps to Reproduce
/api/user/:usernamefor any user.livePromise(line 53) never resolves/rejects.Expected Behavior
Every outbound
fetch()should have anAbortControllerwith a 15-second timeout that cleanly aborts and triggers the existing error/fallback paths.Actual Behavior
Zero timeout configuration. If a remote API hangs, the server hangs with it.
Suggested Fix
Create a reusable helper in
fetch-user-info.js:Replace both
fetch(rawUrl)andfetch(liveApiUrl)calls withfetchWithTimeout(...).Affected Files
scripts/fetch-user-info.js(lines 25, 53)server.js(line 204 — ensure timeout is respected)