jackwener/OpenCLI · error · CommandExecutionError
Failed to read hupu hot threads: ${message}
Error message
Failed to read hupu hot threads: ${message} What it means
getHupuHot navigates to bbs.hupu.com and runs buildHotScript(limit) inside the page to extract hot thread rows. If that page.evaluate throws (page unreachable, script error, markup mismatch causing a runtime exception), the error is wrapped as CommandExecutionError with the hint that the site may be unreachable or its markup changed.
Source
Thrown at clis/hupu/hot.js:132
// hydrating; bbs.hupu.com is mostly SSR so this returns fast.
const start = Date.now();
while (document.querySelectorAll('.t-info').length === 0 && Date.now() - start < 5000) {
await new Promise(r => setTimeout(r, 100));
}
return extractHupuHotRowsFromDoc(document, ${JSON.stringify(limit)}, parseHupuCount);
})()
`;
}
async function getHupuHot(page, args) {
const limit = normalizeHotLimit(args.limit);
await page.goto(`${HUPU_HOST}/`, { waitUntil: 'load', settleMs: 1000 });
let rows;
try {
rows = await page.evaluate(buildHotScript(limit));
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
throw new CommandExecutionError(
`Failed to read hupu hot threads: ${message}`,
'bbs.hupu.com may be unreachable or its markup may have changed',
);
}
if (!Array.isArray(rows) || rows.length === 0) {
throw new EmptyResultError(
'hupu/hot',
'No threads found on bbs.hupu.com — page structure may have changed',
);
}
return rows;
}
export const hotCommand = cli({
site: 'hupu',
name: 'hot',
access: 'read',
description: '虎扑首页热门帖子(含 lights / replies / forum / is_hot 列)',View on GitHub (pinned to 49907e53dc)
Solutions
- Retry the command — transient network or 5xx issues often resolve
- Open https://bbs.hupu.com/ in a browser to confirm reachability and that the hot list renders
- Inspect the inner error message (wrapped in this error) to see what the in-page script choked on
- If markup changed, update buildHotScript selectors in clis/hupu/hot.js
Example fix
// before
const rows = await getHupuHot(page, 50);
// after
let rows;
try { rows = await getHupuHot(page, 50); }
catch (e) {
console.error(e.message); // includes inner cause + hint
rows = [];
} Defensive patterns
Strategy: retry
Validate before calling
const reachable = await fetch('https://bbs.hupu.com/', { method: 'HEAD' }).then(r => r.ok).catch(() => false);
if (!reachable) throw new Error('bbs.hupu.com unreachable — check network'); Type guard
function isHotRows(v) {
return Array.isArray(v) && v.length > 0 && v.every(r => r && typeof r === 'object');
} Try / catch
try {
rows = await getHupuHot(page, limit);
} catch (e) {
if (/Failed to read hupu hot threads/.test(e.message)) {
await sleep(3000); rows = await getHupuHot(page, limit); // one retry
} else throw e;
} Prevention
- Retry once with backoff before failing — many causes are transient
- Monitor bbs.hupu.com reachability from your runtime environment
- Re-check buildHotScript selectors after Hupu redesigns
- Use a realistic user-agent/profile to reduce anti-bot interference
When it happens
Trigger: page.goto to bbs.hupu.com succeeds but the injected buildHotScript evaluate throws — timeout, navigation interrupted, selectors/DOM assumptions in the script breaking, or the page serving an error/anti-bot page with no expected structure.
Common situations: No network access or DNS failure to bbs.hupu.com; Hupu redesigned the hot-list markup; anti-bot interstitial (captcha) replacing the homepage; transient 5xx from Hupu; slow load exceeding settle/wait budgets.
Related errors
- ${label} failed: ${error?.message ?? error}
- Read Hupu mentions failed: ${result.error || 'unknown error'
- weixin search failed while loading Sogou results
- 1point3acres request failed: ${error?.message || error}
- 1point3acres request failed: HTTP ${res.status} ${res.status
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/7aa91310340477dd.
Report an issue: GitHub.