jackwener/OpenCLI · error · CliError
FETCH_ERROR
FETCH_ERROR
Error message
Sina API HTTP ${res.status} What it means
CliError with code FETCH_ERROR thrown by fetchGBK when a Sina API endpoint (suggest or quote, called via suggestRaw/hqRaw) returns a non-ok HTTP status. The status code is interpolated. fetchGBK sets a Referer header because Sina requires it, so failures usually mean blocking or upstream issues rather than missing headers.
Source
Thrown at clis/sinafinance/stock.js:16
/**
* Sinafinance stock quote — A股 / 港股 / 美股
*
* Uses two public Sina APIs (no browser required):
* suggest3.sinajs.cn — symbol search
* hq.sinajs.cn — real-time quote
*/
import { cli, Strategy } from '@jackwener/opencli/registry';
import { CliError } from '@jackwener/opencli/errors';
const MARKET_CN = '11';
const MARKET_HK = '31';
const MARKET_US = '41';
async function fetchGBK(url) {
const res = await fetch(url, { headers: { Referer: 'https://finance.sina.com.cn' } });
if (!res.ok)
throw new CliError('FETCH_ERROR', `Sina API HTTP ${res.status}`, 'Check your network');
const buf = await res.arrayBuffer();
return new TextDecoder('gbk').decode(buf);
}
function parseSuggest(raw, markets) {
const m = raw.match(/suggestvalue="(.*)"/s);
if (!m)
return [];
return m[1].split(';').filter(Boolean).map(s => {
const p = s.split(',');
return { name: p[4] || p[0] || '', market: p[1] || '', symbol: p[3] || '' };
}).filter(e => markets.includes(e.market));
}
function hqSymbol(e) {
if (e.market === MARKET_HK)
return `hk${e.symbol}`;
if (e.market === MARKET_US)
return `gb_${e.symbol}`;
return e.symbol; // A股: already "sh600519" / "sz300XXX"View on GitHub (pinned to 49907e53dc)
Solutions
- Check the interpolated status: 403 → blocked/throttled, 404 → endpoint moved, 5xx → Sina outage
- Slow down request rate and add delays between lookups
- Ensure requests include the Referer header (the library sets this; custom forks must too)
- For 404, verify the current Sina endpoint URLs and update the code
Defensive patterns
Strategy: retry
Try / catch
try {
const stock = await cli.stock({ key, market });
} catch (err) {
if (err.code === 'FETCH_ERROR') {
const m = err.message.match(/HTTP (\d+)/);
if (m && m[1] === '403') await sleep(30_000); // throttled/blocked
else if (m && Number(m[1]) >= 500) return retryLater();
throw err;
}
throw err;
} Prevention
- Keep request volume low; Sina aggressively rate-limits suggest/quote endpoints
- Never strip the Referer header (https://finance.sina.com.cn) if forking
- Expect 403 from datacenter IPs; run from residential/allowed networks
- Distinguish FETCH_ERROR (HTTP) from network failures before retrying
When it happens
Trigger: Any call to fetchGBK — symbol suggestion or realtime quote lookups — where the Sina endpoint returns 403 (Referer/bot detection, rate limiting), 404 (endpoint change), or 5xx (outage).
Common situations: Hammering suggest/quote endpoints causing 403 rate limits; Sina blocking datacenter IPs; endpoint deprecation after Sina API changes; Sina CDN incidents returning 5xx.
Related errors
- archive snapshots failed: HTTP ${resp.status}
- DuckDuckGo suggest returned HTTP ${resp.status}
- Instagram private publish ${stage} failed: ${response.status
- Failed to fetch followers: HTTP ' + r2.status
- Failed to fetch following: HTTP ' + r2.status
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/689da1057214f13b.
Report an issue: GitHub.