{"record":{"id":"3ac0f44b4ddfa688","repo":"jackwener/OpenCLI","slug":"label-request-failed-err-message","errorCode":null,"errorMessage":"${label} request failed: ${err.message}","messagePattern":"(.+?) request failed: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"critical","filePath":"clis/openfda/utils.js","lineNumber":31,"sourceCode":"        throw new ArgumentError(`--${name} is required`);\n    }\n    return value.trim();\n}\n\nexport function requireBoundedInt(value, def, max, name = 'limit') {\n    const n = value == null || value === '' ? def : Number(value);\n    if (!Number.isInteger(n) || n < 1 || n > max) {\n        throw new ArgumentError(`--${name} must be an integer between 1 and ${max}`);\n    }\n    return n;\n}\n\nexport async function openfdaFetch(url, label) {\n    let resp;\n    try {\n        resp = await fetch(url, { headers: { 'User-Agent': UA, accept: 'application/json' } });\n    } catch (err) {\n        throw new CommandExecutionError(`${label} request failed: ${err.message}`);\n    }\n    if (resp.status === 404) {\n        // openFDA returns 404 for \"no matches\" instead of an empty results array.\n        throw new EmptyResultError(label, `${label} returned 404 (no matches).`);\n    }\n    if (resp.status === 429) {\n        throw new CommandExecutionError(`${label} rate-limited (HTTP 429); back off and retry.`);\n    }\n    if (!resp.ok) {\n        throw new CommandExecutionError(`${label} returned HTTP ${resp.status}.`);\n    }\n    let body;\n    try {\n        body = await resp.json();\n    } catch (err) {\n        throw new CommandExecutionError(`${label} returned non-JSON body: ${err.message}`);\n    }\n    return body;","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/openfda/utils.js#L13-L49","documentation":"openfdaFetch wraps the network call to api.fda.gov; if fetch itself rejects (DNS failure, connection refused, TLS error, timeout) it rethrows as CommandExecutionError '<label> request failed: <cause>'. This distinguishes transport-level failures from HTTP status errors, which are handled separately. The label identifies which openfda command's request died.","triggerScenarios":"No network connectivity; DNS cannot resolve api.fda.gov; a proxy blocks outbound HTTPS; TLS interception breaks the handshake; firewall drops the connection. Any openfda command (drug-label, food-recall) triggers it at fetch time.","commonSituations":"Laptop offline or on a VPN that blocks api.fda.gov; corporate MITM proxy with an untrusted cert; transient DNS outage; IPv6 misconfiguration forcing failed connections.","solutions":["Verify connectivity: curl -v https://api.fda.gov/food/enforcement.json?limit=1.","Check DNS resolution of api.fda.gov (nslookup) and proxy env vars (HTTP_PROXY/HTTPS_PROXY).","Retry after confirming the network is up; the underlying fetch error message names the root cause.","If behind a TLS-intercepting proxy, install the proxy's CA cert so Node trusts it (NODE_EXTRA_CA_CERTS)."],"exampleFix":"// before\nconst body = await openfdaFetch(url, 'openfda drug-label'); // network down\n// after\ntry {\n  const body = await openfdaFetch(url, 'openfda drug-label');\n} catch (e) {\n  await new Promise(r => setTimeout(r, 2000));\n  const body = await openfdaFetch(url, 'openfda drug-label'); // simple retry\n}","handlingStrategy":"retry","validationCode":"async function assertOpenfdaReachable() {\n  const r = await fetch('https://api.fda.gov/food/enforcement.json?limit=1');\n  if (!r) throw new Error('api.fda.gov unreachable');\n  return true;\n}","typeGuard":"function isNetworkError(e) {\n  return e instanceof Error && /request failed:/.test(e.message) &&\n    /(ENOTFOUND|ECONNREFUSED|EAI_AGAIN|CERT|ETIMEDOUT)/.test(e.message);\n}","tryCatchPattern":"try {\n  const body = await openfdaFetch(url, 'openfda drug-label');\n} catch (e) {\n  if (/request failed:/.test(e.message)) {\n    await new Promise(r => setTimeout(r, 2000));\n    return openfdaFetch(url, 'openfda drug-label'); // one retry\n  }\n  throw e;\n}","preventionTips":["Check DNS/proxy reachability of api.fda.gov before batch jobs.","Configure NODE_EXTRA_CA_CERTS behind TLS-intercepting proxies.","Add exponential backoff with a retry cap for transport errors.","Log the underlying err.message — it names the exact network cause."],"tags":["network","dns","fetch","openfda"],"backgroundTag":"connection-refused","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}