jackwener/OpenCLI · error · CommandExecutionError
${label} request failed: ${err?.message ?? err}
Error message
${label} request failed: ${err?.message ?? err} What it means
tvmazeFetch wraps the underlying fetch() call and converts network-level failures into CommandExecutionError with remediation advice. This error means the request to api.tvmaze.com never completed — DNS, TCP, TLS, or connection failure — not that the API returned an error status.
Source
Thrown at clis/tvmaze/utils.js:46
export function requireBoundedInt(value, defaultValue, maxValue, label = 'limit') {
const raw = value ?? defaultValue;
const n = typeof raw === 'number' ? raw : Number(raw);
if (!Number.isInteger(n) || n <= 0) {
throw new ArgumentError(`tvmaze ${label} must be a positive integer`);
}
if (n > maxValue) {
throw new ArgumentError(`tvmaze ${label} must be <= ${maxValue}`);
}
return n;
}
export async function tvmazeFetch(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 api.tvmaze.com is reachable from this network.',
);
}
if (resp.status === 404) {
throw new EmptyResultError(label, `TVmaze returned 404 for ${url}.`);
}
if (resp.status === 429) {
throw new CommandExecutionError(
`${label} returned HTTP 429 (rate limited)`,
'TVmaze caps unauthenticated traffic at ~20 req/10s; wait a few seconds and retry.',
);
}
if (!resp.ok) {
throw new CommandExecutionError(`${label} returned HTTP ${resp.status}`);
}
let body;
try {View on GitHub (pinned to 49907e53dc)
Solutions
- Verify network connectivity and that api.tvmaze.com resolves and is reachable (curl -v https://api.tvmaze.com/shows/1)
- Check proxy/VPN/firewall settings; set HTTPS_PROXY if your environment requires one
- Retry after a short wait in case of a transient outage
- Read err.message in the error text — it names the underlying cause (ENOTFOUND, ECONNREFUSED, timeout, etc.)
Example fix
// before (no handling, hard crash)
await tvmazeFetch(url, 'shows');
// after
try { await tvmazeFetch(url, 'shows'); }
catch (e) { console.error('TVmaze unreachable, check network:', e.message); process.exitCode = 1; } Defensive patterns
Strategy: retry
Validate before calling
import { lookup } from 'node:dns/promises';
async function canReachTvmaze() {
try { await lookup('api.tvmaze.com'); return true; }
catch { return false;
}
}
// gate the call: if (!(await canReachTvmaze())) { console.error('TVmaze unreachable'); } Type guard
function isNetworkError(err) {
return err && (err.cause?.code === 'ENOTFOUND' ||
err.cause?.code === 'ECONNREFUSED' ||
err.cause?.code === 'ECONNRESET' ||
/request failed/.test(String(err.message)));
} Try / catch
try {
const data = await tvmazeFetch(url, 'shows');
} catch (err) {
if (/request failed/.test(err.message)) {
console.error('Network problem reaching TVmaze:', err.message);
// optional: retry with backoff
} else throw err;
} Prevention
- Wrap tvmazeFetch calls in try/catch and treat 'request failed' as a network problem
- Add retry with exponential backoff for transient failures
- Verify DNS/proxy/VPN configuration in restricted environments
- Cache API responses to reduce dependence on connectivity
When it happens
Trigger: fetch() throws for the request to api.tvmaze.com: DNS resolution failure, no network route, connection refused/timeout, TLS error, or a proxy blocking the request.
Common situations: Working offline or on a captive-portal Wi-Fi, corporate firewall/VPN blocking the host, DNS misconfiguration, or api.tvmaze.com outage.
Related errors
- `${label} request failed: ${err?.message ?? err}`
- ${label} request failed: ${err?.message ?? err}
- FETCH_ERROR
- Network failure fetching ${label}: ${detail}
- Failed to fetch WeRead search page: ${error instanceof Error
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/35a78d9bc259cf3a.
Report an issue: GitHub.