{"record":{"id":"21ca9a4c118a5e5c","repo":"jackwener/OpenCLI","slug":"label-request-failed-err-message-err-21ca9a","errorCode":null,"errorMessage":"${label} request failed: ${err?.message ?? err}","messagePattern":"(.+?) request failed: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"critical","filePath":"clis/osv/utils.js","lineNumber":103,"sourceCode":"\nasync function readJson(resp, label) {\n    let body;\n    try {\n        body = await resp.json();\n    }\n    catch (err) {\n        throw new CommandExecutionError(`${label} returned malformed JSON: ${err?.message ?? err}`);\n    }\n    return body;\n}\n\nexport async function osvGet(url, label) {\n    let resp;\n    try {\n        resp = await fetch(url, { headers: { 'user-agent': UA, accept: 'application/json' } });\n    }\n    catch (err) {\n        throw new CommandExecutionError(\n            `${label} request failed: ${err?.message ?? err}`,\n            'Check that api.osv.dev is reachable from this network.',\n        );\n    }\n    if (resp.status === 404) {\n        throw new EmptyResultError(label, `OSV.dev returned 404 for ${url}.`);\n    }\n    if (resp.status === 429) {\n        throw new CommandExecutionError(`${label} returned HTTP 429 (rate limited)`);\n    }\n    if (!resp.ok) {\n        throw new CommandExecutionError(`${label} returned HTTP ${resp.status}`);\n    }\n    return readJson(resp, label);\n}\n\nexport async function osvPost(url, payload, label) {\n    let resp;","sourceCodeStart":85,"sourceCodeEnd":121,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/osv/utils.js#L85-L121","documentation":"osvGet wraps the fetch call so low-level network failures (DNS resolution, connection refused/reset, TLS errors, timeouts) become CommandExecutionError with a hint to check api.osv.dev reachability. This fires before any HTTP status is available.","triggerScenarios":"fetch() rejects: no DNS entry for api.osv.dev, connection refused, TLS handshake failure, offline network, or a proxy blocking the request.","commonSituations":"Being offline or on a restricted corporate network; DNS blocked for api.osv.dev; firewall egress rules; misconfigured HTTPS_PROXY; transient network outage.","solutions":["Verify network connectivity and that https://api.osv.dev resolves (curl -I https://api.osv.dev).","Check proxy configuration (HTTPS_PROXY/NO_PROXY) if behind a corporate proxy.","Retry with backoff for transient outages.","Check firewall/egress rules allow HTTPS to api.osv.dev."],"exampleFix":"// before\nconst body = await osvGet(url, label); // throws on network failure\n// after\ntry {\n  const body = await osvGet(url, label);\n} catch (e) {\n  if (/request failed/.test(e.message)) {\n    console.error('api.osv.dev unreachable; check network/proxy');\n  }\n  throw e;\n}","handlingStrategy":"retry","validationCode":"const reachable = await fetch('https://api.osv.dev/v1/query', { method: 'HEAD' })\n  .then((r) => true)\n  .catch(() => false);\nif (!reachable) throw new Error('api.osv.dev is not reachable; check network/proxy before running OSV queries');","typeGuard":"const isNetworkError = (err) =>\n  err instanceof Error && /fetch failed|ENOTFOUND|ECONNREFUSED|EAI_AGAIN|certificate|timeout/i.test(err.message);","tryCatchPattern":"try {\n  const body = await osvGet(url, label);\n} catch (e) {\n  if (e instanceof CommandExecutionError && /request failed/.test(e.message)) {\n    console.error('api.osv.dev unreachable — checking connectivity');\n    return retryWithBackoff(() => osvGet(url, label), 3, 500);\n  }\n  throw e;\n}","preventionTips":["Add a pre-flight reachability check to api.osv.dev in CI pipelines.","Configure and verify HTTPS_PROXY/NO_PROXY for corporate networks.","Retry with exponential backoff for transient DNS/connection failures.","Allowlist api.osv.dev in firewall egress rules."],"tags":["network","dns","connection","http"],"backgroundTag":"connection-refused","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}