jackwener/OpenCLI · error · CommandExecutionError
eastmoney convertible failed: HTTP ${resp.status}
Error message
eastmoney convertible failed: HTTP ${resp.status} What it means
CommandExecutionError thrown after fetch (clis/eastmoney/convertible.js:151) when the HTTP response from push2.eastmoney.com/api/qt/clist/get has a non-2xx status (`!resp.ok`). The message embeds the status code. It wraps any server-side rejection — rate limiting, WAF block, token rejection, or upstream outage — into a single CLI-level failure.
Source
Thrown at clis/eastmoney/convertible.js:151
const sortKey = String(args.sort ?? 'turnover').toLowerCase();
const sort = SORTS[sortKey];
if (!sort) throw new ArgumentError(`Unknown sort "${sortKey}". Valid: ${Object.keys(SORTS).join(', ')}`);
const limit = parseConvertibleLimit(args.limit);
const url = new URL('https://push2.eastmoney.com/api/qt/clist/get');
url.searchParams.set('pn', '1');
url.searchParams.set('pz', String(limit));
url.searchParams.set('po', sort.order === 'desc' ? '1' : '0');
url.searchParams.set('np', '1');
url.searchParams.set('fltt', '2');
url.searchParams.set('invt', '2');
url.searchParams.set('fid', sort.fid);
url.searchParams.set('fs', 'b:MK0354');
url.searchParams.set('fields', 'f12,f14,f2,f3,f6,f229,f230,f232,f234,f235,f236,f237,f238,f239,f243');
url.searchParams.set('ut', 'bd1d9ddb04089700cf9c27f6f7426281');
const resp = await fetch(url, { headers: { 'User-Agent': 'Mozilla/5.0' } });
if (!resp.ok) throw new CommandExecutionError(`eastmoney convertible failed: HTTP ${resp.status}`);
let data;
try {
data = await resp.json();
} catch (error) {
throw new CommandExecutionError(`eastmoney convertible returned invalid JSON: ${error?.message ?? error}`);
}
const diff = extractConvertibleDiff(data);
return mapConvertibleRows(diff, limit);
},
});
export const __test__ = { SORTS, extractConvertibleDiff, mapConvertibleRow, mapConvertibleRows, parseConvertibleLimit };
View on GitHub (pinned to 49907e53dc)
Solutions
- Read the status in the message: 403 → token/WAF issue, 429 → back off and slow the request rate, 5xx → retry later.
- Retry with exponential backoff; transient 5xx/429 usually clear.
- Send a realistic browser User-Agent (the CLI sends 'Mozilla/5.0'; a fuller UA string helps against WAF).
- Check network path — disable VPN/proxy or try a residential IP if blocked.
- Verify the endpoint is up by curling the exact URL and inspecting status/headers.
Example fix
// before
const resp = await fetch(url, { headers: { 'User-Agent': 'Mozilla/5.0' } });
if (!resp.ok) throw new CommandExecutionError(`eastmoney convertible failed: HTTP ${resp.status}`);
// after
const resp = await fetch(url, { headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)' } });
if (resp.status === 429 || resp.status >= 500) {
await new Promise(r => setTimeout(r, 2000));
return fetchConvertible(); // retry once with backoff
}
if (!resp.ok) throw new CommandExecutionError(`eastmoney convertible failed: HTTP ${resp.status}`); Defensive patterns
Strategy: retry
Validate before calling
// Nothing to validate pre-call; validate status post-call:
const resp = await fetch(url);
if (resp.status === 429 || resp.status >= 500) return retryWithBackoff();
if (!resp.ok) throw new Error(`HTTP ${resp.status}`); Try / catch
try {
const rows = await convertibleRows();
} catch (e) {
const m = String(e.message).match(/HTTP (\d+)/);
if (m) {
const status = Number(m[1]);
if (status === 429 || status >= 500) return retryWithBackoff(convertibleRows, 3);
if (status === 403) console.error('blocked: rotate IP/User-Agent or refresh ut token');
}
throw e;
} Prevention
- Rate-limit requests to push2 (e.g. ≥1s spacing) to avoid 429.
- Use a full browser User-Agent string to reduce WAF 403s.
- Back off exponentially on 5xx/429 instead of immediate retries.
- Monitor the ut token — replace it when 403s start appearing.
- Prefer residential IPs over datacenter ranges for eastmoney endpoints.
When it happens
Trigger: Any fetch to the clist endpoint returning 4xx/5xx: 403 from eastmoney's WAF for suspicious IPs or missing/rotated `ut` token, 429 from request-rate limits, 5xx from push2 outages, or proxy errors surfacing as non-OK statuses.
Common situations: Running from datacenter/cloud IPs commonly blocked by eastmoney; hammering the endpoint in a loop and tripping 429; eastmoney rotating the `ut` token causing 403; corporate proxies or firewalls rejecting the request; push2 maintenance windows returning 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
- HTTP_ERROR
- 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/572721ecded6865d.
Report an issue: GitHub.