jackwener/OpenCLI · warning · EmptyResultError
eastmoney convertible
Error message
eastmoney convertible
What it means
EmptyResultError('eastmoney convertible') thrown by extractConvertibleDiff (clis/eastmoney/convertible.js:71) when the response parsed fine and `data.data.diff` is an array, but the array has zero elements. The API responded successfully yet no convertible-bond rows matched the query. This is treated as an expected, distinguishable empty result rather than a hard failure.
Source
Thrown at clis/eastmoney/convertible.js:71
if (!/^\d+$/.test(raw)) throw new ArgumentError('eastmoney convertible --limit must be an integer between 1 and 100');
const parsed = Number(raw);
if (parsed < 1 || parsed > 100) throw new ArgumentError('eastmoney convertible --limit must be an integer between 1 and 100');
return parsed;
}
export function extractConvertibleDiff(data) {
if (!data || typeof data !== 'object' || Array.isArray(data)) {
throw new CommandExecutionError('eastmoney convertible returned a malformed response envelope');
}
if (!data.data || typeof data.data !== 'object' || Array.isArray(data.data)) {
throw new CommandExecutionError('eastmoney convertible returned a malformed data envelope');
}
const diff = data.data.diff;
if (!Array.isArray(diff)) {
throw new CommandExecutionError('eastmoney convertible returned malformed diff data');
}
if (diff.length === 0) {
throw new EmptyResultError('eastmoney convertible');
}
return diff;
}
// Map a raw eastmoney clist `diff` item to an output row.
//
// #2109: f238 / f239 were previously emitted as `remainingYears` / `ytm`, but
// cross-verification (12/12 fingerprint hits) shows f239 is the putback trigger
// price (= convPrice × 0.7) and f238 is the pure-bond premium %. Real YTM /
// remaining term are not in this response's `fields`; adding the correct f-codes
// is a follow-up that needs a live push2 field dump cross-checked against jisilu.
export function mapConvertibleRow(it, rank) {
if (!it || typeof it !== 'object' || Array.isArray(it)) {
throw new CommandExecutionError(`eastmoney convertible returned malformed row at rank ${rank}`);
}
const bondCode = normalizeEastmoneyIdentityString(it.f12, 'f12', '');
const bondName = normalizeEastmoneyIdentityString(it.f14, 'f14', bondCode);
const stockCode = normalizeEastmoneyIdentityString(it.f232, 'f232', bondCode);View on GitHub (pinned to 49907e53dc)
Solutions
- Retry later — empty results during off-hours/maintenance often resolve.
- Verify with the browser-facing eastmoney convertible bond page that the board currently has listings.
- Test the exact push2 URL manually to see whether diff is empty for everyone or just your client (indicates soft block).
- Refresh the `ut` token and field list if the API started returning empty payloads for this client.
- Handle EmptyResultError distinctly in callers so a truly empty market isn't retried as a failure.
Example fix
// before
const rows = await runConvertible();
// after
try {
const rows = await runConvertible();
} catch (e) {
if (e.name === 'EmptyResultError') return [];
throw e;
} Defensive patterns
Strategy: try-catch
Validate before calling
// No pre-call validation can predict an empty board; detect post-hoc: // EmptyResultError is thrown for diff.length === 0.
Try / catch
try {
const rows = await convertibleDiff();
} catch (e) {
if (e.name === 'EmptyResultError') {
return []; // legitimate empty market result — do not retry
}
throw e;
} Prevention
- Distinguish EmptyResultError from CommandExecutionError — only the latter warrants retries.
- Retry empty results at most once with a delay before giving up.
- Cross-check the eastmoney web UI to confirm the board is genuinely empty.
- Watch for a sudden stream of empty results from one client — a sign of soft blocking.
When it happens
Trigger: The push2 clist query with fs=b:MK0354 returns an empty diff array — e.g. the board has no listed convertibles at query time, filters/sort fid produce no rows, or the backend soft-restricts the client and returns an empty success. Raised inside `diff` via extractConvertibleDiff after a valid HTTP 200 + JSON parse.
Common situations: Running during market-data maintenance windows; querying from a region/IP where the MK0354 board data is withheld; using an outdated `ut` token that yields empty results instead of an error; genuinely empty board after delistings.
Understand the failure class
Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.
Related errors
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/255d9205d24b52d6.
Report an issue: GitHub.