jackwener/OpenCLI · error · CommandExecutionError
toutiao hot-board returned error: ${payload.error || payload
Error message
toutiao hot-board returned error: ${payload.error || payload.message} What it means
If the parsed hot-board JSON contains an `error` or `message` field, the command throws this CommandExecutionError carrying that upstream message. It means the API signalled a specific failure (rate limit notice, permission denial, endpoint deprecation) inside an otherwise successful-looking JSON envelope.
Source
Thrown at clis/toutiao/hot.js:53
},
});
} catch (error) {
throw new CommandExecutionError(`toutiao hot-board request failed: ${error?.message || error}`);
}
if (!resp.ok) {
throw new CommandExecutionError(`toutiao hot-board failed: HTTP ${resp.status}`);
}
let payload;
try {
payload = await resp.json();
} catch (error) {
throw new CommandExecutionError(`toutiao hot-board returned malformed JSON: ${error?.message || error}`);
}
if (payload?.status && payload.status !== 'success') {
throw new CommandExecutionError(`toutiao hot-board returned status=${payload.status}`);
}
if (payload?.error || payload?.message) {
throw new CommandExecutionError(`toutiao hot-board returned error: ${payload.error || payload.message}`);
}
const list = Array.isArray(payload?.data) ? payload.data : [];
const rows = list.map(mapHotRow).filter(Boolean).slice(0, limit);
if (rows.length === 0) {
throw new EmptyResultError('toutiao hot', '上游 hot-board 返回空列表。');
}
// Re-rank (1..N) after filter so ranks are dense even if upstream had nulls.
return rows.map((row, idx) => ({ ...row, rank: idx + 1 }));
},
});
View on GitHub (pinned to 49907e53dc)
Solutions
- Read the embedded error/message text — it names the upstream cause (rate limit, forbidden, deprecated).
- If rate-limited, back off and slow request frequency; reuse one session rather than hammering.
- If the message indicates the endpoint moved/deprecated, locate the new hot-board URL (from the toutiao.com homepage network panel) and update HOT_BOARD_URL in clis/toutiao/utils.js.
- Retry later if the message signals temporary unavailability.
Example fix
// before
if (payload?.error || payload?.message) {
throw new CommandExecutionError(`toutiao hot-board returned error: ${payload.error || payload.message}`);
}
// after — some payloads use message for non-error notices
if (payload?.error || (payload?.message && payload.status !== 'success')) {
throw new CommandExecutionError(`toutiao hot-board returned error: ${payload.error || payload.message}`);
} Defensive patterns
Strategy: try-catch
Validate before calling
// treat any error/message envelope as a failure signal before mapping rows const hasUpstreamError = (p) => p && typeof p === 'object' && Boolean(p.error || (p.message && p.status !== 'success'));
Type guard
function hasUpstreamError(p) {
return p !== null && typeof p === 'object' &&
(typeof p.error === 'string' && p.error.length > 0 ||
typeof p.message === 'string' && p.message.length > 0 && p.status !== 'success');
} Try / catch
try {
const rows = await toutiaoHot({ limit: 30 });
} catch (e) {
if (/returned error:/.test(e.message)) {
// upstream reported a specific problem (rate limit/deprecated) — read the
// message after the colon and adjust frequency or endpoint accordingly
console.error(e.message);
return fallbackHotSource();
}
throw e;
} Prevention
- Keep request rates low so the upstream never emits rate-limit messages.
- Log the upstream error text — it usually says exactly what to change.
- Maintain a fallback data source for the hot list when Toutiao signals denial.
- Subscribe to/monitor the endpoint so deprecation messages are caught before breaking users.
When it happens
Trigger: Calling `toutiao hot` when the endpoint responds with JSON containing error/message fields such as {message:'请求过于频繁'} (rate limit), {error:'forbidden'}, or a deprecation/parameter notice.
Common situations: Toutiao's anti-scraping layer returns a JSON notice instead of data after too many requests; API version deprecated with a message telling callers to migrate; regional/IP restrictions returned as a JSON message.
Related errors
- toutiao hot-board returned status=${payload.status}
- API_ERROR
- API_ERROR
- coingecko derivatives returned HTTP 429 (rate limited)
- Ctrip flight API failed (status=${String(payload?.status)}):
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/ae3c8403b3ec81fc.
Report an issue: GitHub.