Skip to content

fix: add timeouts to build-time network requests#570

Open
MatrixNeoKozak wants to merge 2 commits into
vllm-project:mainfrom
MatrixNeoKozak:fix/improvement-1781799500531
Open

fix: add timeouts to build-time network requests#570
MatrixNeoKozak wants to merge 2 commits into
vllm-project:mainfrom
MatrixNeoKozak:fix/improvement-1781799500531

Conversation

@MatrixNeoKozak

Copy link
Copy Markdown

The build-time scripts fetch-hf-dates.mjs and fetch-provider-logos.mjs performed network requests to the HuggingFace API and external resources without any timeout configurations. In scenarios of network instability or API latency, these scripts could stall indefinitely, blocking the entire pnpm build pipeline. I have implemented an AbortController with a 10-second timeout for all fetch requests within these scripts to ensure the build process remains robust and fails fast in the event of unreachable external services.

@vercel

vercel Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
vllm-recipes Ready Ready Preview, Comment Jun 25, 2026 3:50pm

Request Review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a custom fetchWithTimeout helper to prevent hangs when fetching Hugging Face model dates and provider logos. However, the custom implementation clears the timeout as soon as the headers are received, which leaves the subsequent response body streaming unprotected. The reviewer recommends replacing this custom helper with the native AbortSignal.timeout(delay) API, which is cleaner, standard, and covers both the connection and body streaming phases.

Comment thread scripts/fetch-hf-dates.mjs Outdated
Comment on lines 31 to 48
async function fetchWithTimeout(url, options = {}, timeout = 10000) {
const controller = new AbortController();
const id = setTimeout(() => controller.abort(), timeout);
try {
const response = await fetch(url, { ...options, signal: controller.signal });
clearTimeout(id);
return response;
} catch (error) {
clearTimeout(id);
throw error;
}
}

async function fetchCreatedAt(modelId) {
try {
const res = await fetch(`https://huggingface.co/api/models/${modelId}`, {
const res = await fetchWithTimeout(`https://huggingface.co/api/models/${modelId}`, {
headers: { "User-Agent": "vllm-recipes-build/1.0" },
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The custom fetchWithTimeout helper clears the timeout immediately after the fetch promise resolves (when headers are received). However, the response body is read asynchronously afterwards (e.g., await res.json()). If the connection hangs or becomes extremely slow during the body streaming phase, the timeout will have already been cleared, and the script will still stall indefinitely.

Since this project runs in a modern Node.js environment (supporting global fetch), you can use the native AbortSignal.timeout(delay) API. This is much cleaner, standard, and automatically covers both the connection phase and the body streaming phase, completely eliminating the need for a custom fetchWithTimeout helper.

async function fetchCreatedAt(modelId) {
  try {
    const res = await fetch("https://huggingface.co/api/models/" + modelId, {
      headers: { "User-Agent": "vllm-recipes-build/1.0" },
      signal: AbortSignal.timeout(10000),
    });

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Replaced custom fetchWithTimeout helper with native AbortSignal.timeout(10000).

Comment thread scripts/fetch-provider-logos.mjs Outdated
Comment on lines 31 to 47
async function fetchWithTimeout(url, options = {}, timeout = 10000) {
const controller = new AbortController();
const id = setTimeout(() => controller.abort(), timeout);
try {
const response = await fetch(url, { ...options, signal: controller.signal });
clearTimeout(id);
return response;
} catch (error) {
clearTimeout(id);
throw error;
}
}

async function fetchOrgAvatarUrl(org) {
const res = await fetch(`https://huggingface.co/${org}`, {
const res = await fetchWithTimeout(`https://huggingface.co/${org}`, {
headers: { "User-Agent": "vllm-recipes-build/1.0" },
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Similar to the other script, the custom fetchWithTimeout helper clears the timeout before the response body is read (e.g., await res.text()). If the connection stalls during the body streaming phase, the script will hang indefinitely.

Using the native AbortSignal.timeout(10000) API simplifies the code and ensures the timeout covers both the connection and the body streaming phases.

async function fetchOrgAvatarUrl(org) {
  const res = await fetch("https://huggingface.co/" + org, {
    headers: { "User-Agent": "vllm-recipes-build/1.0" },
    signal: AbortSignal.timeout(10000),
  });

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Updated fetch to use native AbortSignal.timeout(10000).

Comment thread scripts/fetch-provider-logos.mjs Outdated
continue;
}
const imgRes = await fetch(avatarUrl);
const imgRes = await fetchWithTimeout(avatarUrl);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Update this fetch call to use the native AbortSignal.timeout(10000) API to ensure the image download is fully protected by the timeout.

    const imgRes = await fetch(avatarUrl, { signal: AbortSignal.timeout(10000) });

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Updated fetch to use native AbortSignal.timeout(10000).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant