From 51f3aad5f9a7ec1365121c1eb7a3a8858ed41db0 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 22 Apr 2026 00:04:44 +0530 Subject: [PATCH] fix: add timeout and use HEAD for registry URL validation When --registry-url points to an unreachable host, the CLI hangs indefinitely because fetch() has no timeout and uses GET. This adds: - 5-second timeout via AbortController - HEAD method instead of GET for lightweight validation - Specific error message for timeout vs other network errors Fixes #2027 Co-Authored-By: Paperclip --- src/utils/generate/registry.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/utils/generate/registry.ts b/src/utils/generate/registry.ts index 16fdda2e5..ed578c806 100644 --- a/src/utils/generate/registry.ts +++ b/src/utils/generate/registry.ts @@ -9,11 +9,23 @@ export function registryURLParser(input?: string) { export async function registryValidation(registryUrl?: string, registryAuth?: string, registryToken?: string) { if (!registryUrl) { return; } try { - const response = await fetch(registryUrl as string); + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), 5000); + const response = await fetch(registryUrl as string, { + method: 'HEAD', + signal: controller.signal, + }); + clearTimeout(timeoutId); if (response.status === 401 && !registryAuth && !registryToken) { throw new Error('You Need to pass either registryAuth in username:password encoded in Base64 or need to pass registryToken'); } - } catch { + } catch (error: unknown) { + if (error instanceof Error && error.name === 'AbortError') { + throw new Error(`Registry URL timed out after 5s: ${registryUrl}`); + } + if (error instanceof Error && error.message.startsWith('You Need to pass')) { + throw error; + } throw new Error(`Can't fetch registryURL: ${registryUrl}`); } }