jackwener/OpenCLI · critical · CommandExecutionError

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

Error message

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

What it means

restCountriesFetch wraps the underlying fetch call and throws CommandExecutionError when the network request itself rejects (DNS failure, connection refused, TLS error, timeout). The message includes the command label and the underlying error message, plus a hint to check reachability of restcountries.com. This is a transport-level failure, not an HTTP error status.

Source

Thrown at clis/rest-countries/utils.js:58

export function requireRegion(value) {
    const raw = String(value ?? '').trim().toLowerCase();
    if (!raw) throw new ArgumentError('rest-countries region is required (e.g. "europe", "asia")');
    if (!REST_COUNTRIES_REGIONS.has(raw)) {
        throw new ArgumentError(
            `rest-countries region "${value}" is not recognised`,
            `Allowed regions: ${[...REST_COUNTRIES_REGIONS].join(', ')}.`,
        );
    }
    return raw;
}

export async function restCountriesFetch(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 ?? err}`,
            'Check that restcountries.com is reachable from this network.',
        );
    }
    if (resp.status === 404) {
        throw new EmptyResultError(label, `REST Countries returned 404 for ${url}.`);
    }
    if (resp.status === 429) {
        throw new CommandExecutionError(`${label} returned HTTP 429 (rate limited)`);
    }
    if (!resp.ok) {
        throw new CommandExecutionError(`${label} returned HTTP ${resp.status}`);
    }
    let body;
    try {
        body = await resp.json();
    }
    catch (err) {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Verify network connectivity (curl https://restcountries.com/v3.1/all).
  2. Check DNS resolution of restcountries.com and any proxy settings (HTTP(S)_PROXY env vars).
  3. Retry after transient outages; add backoff around the command.
  4. Catch CommandExecutionError and surface a friendly offline message.

Example fix

// before
const data = await countryCommand({ name: 'japan' });
// after
let data;
try {
  data = await countryCommand({ name: 'japan' });
} catch (err) {
  if (err instanceof CommandExecutionError && /request failed/.test(err.message)) {
    data = await withRetry(() => countryCommand({ name: 'japan' }));
  } else throw err;
}
Defensive patterns

Strategy: retry

Validate before calling

// check reachability before the call
const ok = await fetch('https://restcountries.com/v3.1/all?fields=name')
  .then(r => r.ok).catch(() => false);
if (!ok) throw new Error('restcountries.com is not reachable');

Try / catch

try {
  const data = await countryCommand({ name });
} catch (err) {
  if (err instanceof CommandExecutionError && /request failed/.test(err.message)) {
    // offline/DNS/proxy problem: retry with backoff or degrade gracefully
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: Calling any rest-countries command while restcountries.com is unreachable: no internet, DNS outage, corporate proxy/firewall blocking the domain, or Node lacking network access in a sandbox/CI environment.

Common situations: Running in an offline or air-gapped environment; CI runners without egress; DNS misconfiguration; VPN or firewall rules; IPv6 issues resolving the API host.

Related errors


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