jackwener/OpenCLI · error · CliError
FETCH_ERROR
FETCH_ERROR
Error message
FETCH_ERROR: Unable to reach Apple Podcasts charts for ${country.toUpperCase()} What it means
Thrown by `apple-podcasts top` as a CliError with code FETCH_ERROR when the HTTP request to Apple's charts RSS/API fails at the network level (fetch rejects before a response is received). The message includes the country and the underlying cause (error.cause.code or message) to help diagnose. It covers DNS failures, timeouts (AbortSignal.timeout), TLS errors, and connection resets.
Source
Thrown at clis/apple-podcasts/top.js:30
browser: false,
args: [
{ name: 'limit', type: 'int', default: 20, help: 'Number of podcasts (max 100)' },
{ name: 'country', default: 'us', help: 'Country code (e.g. us, cn, gb, jp)' },
],
columns: ['rank', 'title', 'author', 'id'],
func: async (args) => {
const limit = Math.max(1, Math.min(Number(args.limit), 100));
const country = String(args.country || 'us').trim().toLowerCase();
const url = `${CHARTS_URL}/${country}/podcasts/top/${limit}/podcasts.json`;
let resp;
try {
resp = await fetch(url, {
signal: AbortSignal.timeout(CHARTS_TIMEOUT_MS),
});
}
catch (error) {
const reason = error?.cause?.code ?? error?.message ?? 'unknown network error';
throw new CliError('FETCH_ERROR', `Unable to reach Apple Podcasts charts for ${country.toUpperCase()}`, `Apple charts may be temporarily unavailable (${reason}). Try again later.`);
}
if (!resp.ok)
throw new CliError('FETCH_ERROR', `Charts API HTTP ${resp.status}`, `Check country code: ${country}`);
const data = await resp.json();
const results = data?.feed?.results;
if (!results?.length)
throw new CliError('NOT_FOUND', 'No chart data found', `Try a different country code`);
return results.map((p, i) => ({
rank: i + 1,
title: p.name,
author: p.artistName,
id: p.id,
}));
},
});
View on GitHub (pinned to 49907e53dc)
Solutions
- Check basic connectivity (e.g. curl https://itunes.apple.com) and retry after transient failures
- Verify the timeout is adequate for your network or raise CHARTS_TIMEOUT_MS if configurable
- Check proxy/VPN/firewall settings that may block itunes.apple.com; the error's reason field names the underlying code
- Confirm Apple's charts service status; try a different country code to isolate a regional outage
Example fix
// before
resp = await fetch(url, {}); // no timeout handling
// after
try {
resp = await fetch(url, { signal: AbortSignal.timeout(CHARTS_TIMEOUT_MS) });
} catch (error) {
// retry once, then surface CliError('FETCH_ERROR', ...) with error?.cause?.code
} Defensive patterns
Strategy: retry
Validate before calling
// Cheap pre-flight: is the endpoint reachable at all?
const probe = await fetch('https://itunes.apple.com/', { signal: AbortSignal.timeout(5000) })
.then((r) => r.ok).catch(() => false);
if (!probe) console.log('Network cannot reach itunes.apple.com; fix connectivity before running top.'); Try / catch
try {
await cli.run(['apple-podcasts', 'top', '--country', 'us']);
} catch (e) {
if (e.code === 'FETCH_ERROR' && /Unable to reach/.test(e.message)) {
await new Promise((r) => setTimeout(r, 2000));
// retry once or surface with e.hint's reason
} else throw e;
} Prevention
- Run charts commands only when connectivity to itunes.apple.com is verified
- Account for CHARTS_TIMEOUT_MS on slow links; prefer wired/stable networks in CI
- Set proxy env vars correctly if behind a corporate firewall
- Wrap in retry-with-backoff since the error text explicitly suggests trying later
When it happens
Trigger: `opencli apple-podcasts top --country <cc>` where fetch(url, { signal: AbortSignal.timeout(CHARTS_TIMEOUT_MS) }) rejects — timeout exceeded, DNS failure, offline network, or proxy blocking itunes.apple.com.
Common situations: Offline or firewalled network; corporate proxy blocking Apple domains; charts endpoint temporarily down; CHARTS_TIMEOUT_MS too low on a slow connection.
Related errors
- archive wayback request failed: ${error?.message || error}
- Failed to fetch Chess.com API ${url}: ${error?.message || er
- Failed to refresh Xiaoyuzhou credentials: ${getErrorMessage(
- Failed to reach Xiaoyuzhou API: ${getErrorMessage(error)}
- Failed to fetch Xiaoyuzhou transcript content: ${getErrorMes
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/bfffe4f5a3880209.
Report an issue: GitHub.