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

  1. Retry the command — transient network or 5xx issues often resolve
  2. Open https://bbs.hupu.com/ in a browser to confirm reachability and that the hot list renders
  3. Inspect the inner error message (wrapped in this error) to see what the in-page script choked on
  4. 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

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


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/7aa91310340477dd. Report an issue: GitHub.