jackwener/OpenCLI · error · CommandExecutionError
dongchedi ${contextHint} HTTP ${resp.status}
Error message
dongchedi ${contextHint} HTTP ${resp.status} What it means
A CommandExecutionError raised in dcdFetchPageProps (clis/dongchedi/utils.js:89) when dongchedi.com responded but with a non-2xx status (`!resp.ok`). The message embeds the HTTP status code plus the context hint so the developer knows which command's request failed and how.
Source
Thrown at clis/dongchedi/utils.js:89
* Throws typed errors so callers can let them propagate.
*/
export async function dcdFetchPageProps(path, contextHint) {
let resp;
try {
resp = await fetch(`${DCD_BASE}${path}`, {
headers: {
'User-Agent': UA,
Referer: `${DCD_BASE}/`,
'Accept-Language': 'zh-CN,zh;q=0.9',
},
});
} catch (err) {
throw new CommandExecutionError(
`dongchedi ${contextHint} network error: ${err?.message || err}`,
);
}
if (!resp.ok) {
throw new CommandExecutionError(`dongchedi ${contextHint} HTTP ${resp.status}`);
}
const html = await resp.text();
const pp = extractPageProps(html);
if (!pp) {
throw new CommandExecutionError(
`dongchedi ${contextHint} returned no __NEXT_DATA__`,
'Dongchedi likely changed its page structure, or the request hit an anti-bot page.',
);
}
if (isFallbackShell(pp)) {
throw new CommandExecutionError(
`dongchedi ${contextHint}`,
'Dongchedi served its empty fallback shell — the id may not exist or the URL form changed.',
);
}
return pp;
}
View on GitHub (pinned to 49907e53dc)
Solutions
- Read the status code in the message: 403/429 → slow down, add delays between requests, or retry later from a residential IP; 404 → verify the series id / URL form; 5xx → retry later.
- Add exponential backoff with jitter around dcdFetchPageProps for 429/5xx responses.
- Confirm the URL by opening `https://www.dongchedi.com<path>` in a browser — if the browser also fails, the id or path is wrong.
- Keep the default browser-like User-Agent/Referer headers the library already sends; do not strip them.
- Catch CommandExecutionError and branch on the parsed status to give users an actionable message.
Example fix
// before: hammering the API until 429
for (const id of ids) await dcd.specs(id);
// after: throttle with backoff
for (const id of ids) {
await sleep(1500);
try { await dcd.specs(id); } catch (e) { if (String(e).includes('429')) await retryWithBackoff(); }
} Defensive patterns
Strategy: retry
Try / catch
try {
const pp = await dcdFetchPageProps(path, hint);
} catch (err) {
const m = err.message.match(/HTTP (\d{3})/);
if (m && (m[1] === '429' || m[1].startsWith('5'))) await retryWithBackoff();
else if (m && m[1] === '404') reportBadPath(path);
else throw err;
} Prevention
- Throttle requests (e.g. ≥1s apart) to avoid 429 rate limiting.
- Keep the browser-like User-Agent/Referer headers the library sends.
- Validate series ids/URL paths before fetching to avoid 404s.
- Treat 403 as an IP/WAF problem — switch networks or slow down, don't hammer.
When it happens
Trigger: Any dongchedi command when the server returns 403 (anti-bot/WAF rejection), 429 (rate limiting after rapid repeated calls), 404 (bad URL form or nonexistent series path), or 5xx (server-side outage).
Common situations: Scraping in a tight loop until rate-limited (429), requests flagged by ByteDance's WAF (403) due to datacenter IPs or unusual headers, typos producing invalid paths (404), or dongchedi having a temporary outage (5xx).
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- autohome ${contextHint} HTTP ${resp.status}
- Ctrip flight API returned HTTP ${status || 'unknown'}
- eastmoney convertible failed: HTTP ${resp.status}
- HTTP_ERROR
- HTTP_ERROR
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/078027ecfd4e2036.
Report an issue: GitHub.