jackwener/OpenCLI · critical · CommandExecutionError

${label} request failed: ${err.message}

Error message

${label} request failed: ${err.message}

What it means

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.

Source

Thrown at clis/openfda/utils.js:31

        throw new ArgumentError(`--${name} is required`);
    }
    return value.trim();
}

export function requireBoundedInt(value, def, max, name = 'limit') {
    const n = value == null || value === '' ? def : Number(value);
    if (!Number.isInteger(n) || n < 1 || n > max) {
        throw new ArgumentError(`--${name} must be an integer between 1 and ${max}`);
    }
    return n;
}

export async function openfdaFetch(url, label) {
    let resp;
    try {
        resp = await fetch(url, { headers: { 'User-Agent': UA, accept: 'application/json' } });
    } catch (err) {
        throw new CommandExecutionError(`${label} request failed: ${err.message}`);
    }
    if (resp.status === 404) {
        // openFDA returns 404 for "no matches" instead of an empty results array.
        throw new EmptyResultError(label, `${label} returned 404 (no matches).`);
    }
    if (resp.status === 429) {
        throw new CommandExecutionError(`${label} rate-limited (HTTP 429); back off and retry.`);
    }
    if (!resp.ok) {
        throw new CommandExecutionError(`${label} returned HTTP ${resp.status}.`);
    }
    let body;
    try {
        body = await resp.json();
    } catch (err) {
        throw new CommandExecutionError(`${label} returned non-JSON body: ${err.message}`);
    }
    return body;

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Verify connectivity: curl -v https://api.fda.gov/food/enforcement.json?limit=1.
  2. Check DNS resolution of api.fda.gov (nslookup) and proxy env vars (HTTP_PROXY/HTTPS_PROXY).
  3. Retry after confirming the network is up; the underlying fetch error message names the root cause.
  4. If behind a TLS-intercepting proxy, install the proxy's CA cert so Node trusts it (NODE_EXTRA_CA_CERTS).

Example fix

// before
const body = await openfdaFetch(url, 'openfda drug-label'); // network down
// after
try {
  const body = await openfdaFetch(url, 'openfda drug-label');
} catch (e) {
  await new Promise(r => setTimeout(r, 2000));
  const body = await openfdaFetch(url, 'openfda drug-label'); // simple retry
}
Defensive patterns

Strategy: retry

Validate before calling

async function assertOpenfdaReachable() {
  const r = await fetch('https://api.fda.gov/food/enforcement.json?limit=1');
  if (!r) throw new Error('api.fda.gov unreachable');
  return true;
}

Type guard

function isNetworkError(e) {
  return e instanceof Error && /request failed:/.test(e.message) &&
    /(ENOTFOUND|ECONNREFUSED|EAI_AGAIN|CERT|ETIMEDOUT)/.test(e.message);
}

Try / catch

try {
  const body = await openfdaFetch(url, 'openfda drug-label');
} catch (e) {
  if (/request failed:/.test(e.message)) {
    await new Promise(r => setTimeout(r, 2000));
    return openfdaFetch(url, 'openfda drug-label'); // one retry
  }
  throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/3ac0f44b4ddfa688. Report an issue: GitHub.