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

  1. Retry later — empty results during off-hours/maintenance often resolve.
  2. Verify with the browser-facing eastmoney convertible bond page that the board currently has listings.
  3. Test the exact push2 URL manually to see whether diff is empty for everyone or just your client (indicates soft block).
  4. Refresh the `ut` token and field list if the API started returning empty payloads for this client.
  5. 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

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.