jackwener/OpenCLI · warning · CliError
NO_DATA
NO_DATA
Error message
eastmoney returned no ETF data
What it means
CliError('NO_DATA') thrown in clis/eastmoney/etf.js when the eastmoney ETF ranking API returns HTTP 200 but data.data.diff is missing, not an array, or empty after Array.isArray normalization. The library distinguishes a well-formed-but-empty payload from HTTP failures. It means eastmoney answered successfully but had no 场内ETF (b:MK0021) rows to return.
Source
Thrown at clis/eastmoney/etf.js:52
const limit = Math.max(1, Math.min(Number(args.limit) || 20, 100));
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:MK0021'); // 场内ETF
url.searchParams.set('fields', 'f12,f14,f2,f3,f4,f5,f6,f8');
url.searchParams.set('ut', 'bd1d9ddb04089700cf9c27f6f7426281');
const resp = await fetch(url, { headers: { 'User-Agent': 'Mozilla/5.0' } });
if (!resp.ok) throw new CliError('HTTP_ERROR', `etf 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 ETF data');
return diff.slice(0, limit).map((it, i) => ({
rank: i + 1,
code: it.f12,
name: it.f14,
price: it.f2,
changePercent: it.f3,
change: it.f4,
turnover: it.f6,
volume: it.f5,
turnoverRate: it.f8,
}));
},
});
View on GitHub (pinned to 49907e53dc)
Solutions
- Inspect the raw JSON body to see whether data or diff changed shape.
- Verify fs=b:MK0021 and the fields list still return rows by calling the URL manually.
- Retry later — eastmoney sometimes returns empty payloads during maintenance windows.
- If diff moved, update the parsing path (data.data.diff) to the new location.
- Enrich the error with rc / a body snippet to distinguish upstream rejection from a truly empty universe.
Example fix
// before
const diff = Array.isArray(data?.data?.diff) ? data.data.diff : [];
if (diff.length === 0) throw new CliError('NO_DATA', 'eastmoney returned no ETF data');
// after
const diff = Array.isArray(data?.data?.diff) ? data.data.diff : [];
if (diff.length === 0) throw new CliError('NO_DATA', `eastmoney returned no ETF data (rc=${data?.rc})`); Defensive patterns
Strategy: fallback
Validate before calling
// nothing to validate locally; validate the payload shape right after the response
if (data?.rc !== undefined && data.rc !== 0) throw new CliError('UPSTREAM_REJECTED', `eastmoney rc=${data.rc}`); Type guard
function hasEtfRows(data) {
return data != null && typeof data === 'object'
&& Array.isArray(data?.data?.diff)
&& data.data.diff.length > 0;
} Try / catch
try {
const rows = await fetchEtf({ limit: 10 });
} catch (err) {
if (err instanceof CliError && err.code === 'NO_DATA') {
console.warn('eastmoney returned no ETF rows; using cached fallback dataset');
return loadCachedEtf();
}
throw err;
} Prevention
- Cache the last successful ETF snapshot and fall back to it on NO_DATA.
- Check data.rc / body shape when NO_DATA fires to detect silent schema changes.
- Avoid querying during known eastmoney maintenance/refresh windows.
- Alert on repeated NO_DATA — it usually means the fs universe or diff key changed, not a transient blip.
- Log a truncated response body with the error for faster diagnosis.
When it happens
Trigger: `resp.ok` is true but `data?.data?.diff` is undefined or `[]` at clis/eastmoney/etf.js:52 — e.g. body `{data: null}`, `{"data":{"diff":[]}}`, or an error-shaped JSON with rc != 0.
Common situations: eastmoney silently changing the fs=b:MK0021 universe or fields list, an expired ut token yielding an empty success payload, querying during a data refresh/maintenance window, or the diff key moving in an API schema change.
Related errors
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/62af2848b55ffc18.
Report an issue: GitHub.