jackwener/OpenCLI · error · CliError
HTTP_ERROR
HTTP_ERROR
Error message
eastmoney index-board failed: HTTP ${resp.status} What it means
This CliError with code HTTP_ERROR is thrown when the Eastmoney push2 ulist.np/get endpoint responds with a non-2xx HTTP status. The library checks resp.ok after fetching index quotes and surfaces the upstream status code in the message. It indicates a transport/response problem, not a data problem.
Source
Thrown at clis/eastmoney/index-board.js:71
/** @type {[string,string][]} */
let entries;
if (group === 'all') {
entries = [...INDEX_GROUPS.main, ...INDEX_GROUPS.hk, ...INDEX_GROUPS.us];
} else if (INDEX_GROUPS[group]) {
entries = INDEX_GROUPS[group];
} else {
throw new CliError('INVALID_ARGUMENT', `Unknown group "${group}". Valid: main, hk, us, all`);
}
const secids = entries.map(([secid]) => secid).join(',');
const url = new URL('https://push2.eastmoney.com/api/qt/ulist.np/get');
url.searchParams.set('secids', secids);
url.searchParams.set('fltt', '2');
url.searchParams.set('fields', FIELDS);
url.searchParams.set('ut', 'bd1d9ddb04089700cf9c27f6f7426281');
const resp = await fetch(url, { headers: { 'User-Agent': 'Mozilla/5.0', Accept: 'application/json' } });
if (!resp.ok) throw new CliError('HTTP_ERROR', `eastmoney index-board failed: HTTP ${resp.status}`);
const data = await resp.json();
const diff = Array.isArray(data?.data?.diff) ? data.data.diff : [];
if (diff.length === 0) throw new CliError('NO_DATA', 'eastmoney returned no index data');
// Preserve the order defined in INDEX_GROUPS regardless of API ordering
const byCode = new Map(diff.map((it) => [String(it.f12), it]));
return entries
.map(([secid, fallbackName]) => {
const code = secid.split('.')[1];
const it = byCode.get(code);
if (!it) return null;
return {
code,
name: it.f14 || fallbackName,
price: it.f2,
changePercent: it.f3,
change: it.f4,
open: it.f17,View on GitHub (pinned to 49907e53dc)
Solutions
- Retry with exponential backoff, since 5xx and 429 are often transient
- Slow down request frequency and add jitter to avoid rate limiting/bot detection
- Verify the secids parameter is a well-formed comma list like 1.000001,0.399001 (a malformed list can trigger 400)
- Test the exact URL in a browser or curl with the same User-Agent; if blocked, try a different network/IP
- Check Eastmoney service status; if the endpoint changed, update the API path/params
Example fix
// before
const resp = await fetch(url); // one shot, throws HTTP_ERROR on 429/5xx
// after
for (let i = 0; i < 3; i++) {
try { return await fetchBoard(); }
catch (e) { if (e.code === 'HTTP_ERROR' && i < 2) { await sleep(2 ** i * 500); continue; } throw e; }
} Defensive patterns
Strategy: retry
Validate before calling
function validateSecids(entries) {
const list = entries.map((e) => String(e[0]));
if (list.some((s) => !/^[01]\.\d{6}$/.test(s))) {
throw new Error('Malformed secids; expected e.g. 1.000001,0.399001');
}
return list.join(',');
} Try / catch
try {
const board = await getIndexBoard({ group: 'main' });
} catch (err) {
if (err.code === 'HTTP_ERROR') {
if (err.message.includes('HTTP 429') || /HTTP 5\d\d/.test(err.message)) {
return retryWithBackoff(() => getIndexBoard({ group: 'main' }), 3);
}
throw err; // non-retryable 4xx
}
throw err;
} Prevention
- Throttle request rate and add jitter to avoid Eastmoney bot detection/rate limits
- Implement exponential backoff for 429/5xx statuses
- Send a browser-like User-Agent and Accept header as the library does
- Test the exact request URL with curl when errors persist to distinguish blocking from outages
When it happens
Trigger: Eastmoney returning 4xx/5xx for the ulist.np/get request: rate limiting or bot detection (429/403) due to missing/rejected User-Agent, temporary server errors (5xx), CDN/WAF blocking the client IP, or a malformed secids parameter causing a 400.
Common situations: Bulk-polling index boards and getting throttled by Eastmoney's anti-scraping layer; running from datacenter IPs that are blocked; Eastmoney API changes or outages; corporate proxy stripping the User-Agent header.
Related errors
- eastmoney convertible failed: HTTP ${resp.status}
- HTTP_ERROR
- autohome ${contextHint} HTTP ${resp.status}
- Ctrip flight API returned HTTP ${status || 'unknown'}
- dongchedi ${contextHint} HTTP ${resp.status}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/83803c44014184d2.
Report an issue: GitHub.