jackwener/OpenCLI · error · CommandExecutionError
Failed to extract UISDC news: ${getErrorMessage(error)}
Error message
Failed to extract UISDC news: ${getErrorMessage(error)} What it means
If page.evaluate(buildExtractUisdcNewsJs()) rejects (the injected script threw or the evaluation failed), loadUisdcNews wraps it in CommandExecutionError 'Failed to extract UISDC news: <message>'. This is a low-level extraction failure, distinct from payload validation errors.
Source
Thrown at clis/uisdc/news.js:81
const rows = (Array.isArray(payload.rows) ? payload.rows : [])
.map((row, index) => ({
rank: index + 1,
title: normalizeText(row.title),
summary: normalizeText(row.summary),
url: normalizeText(row.url),
}))
.filter((row) => row.title && row.url);
if (rows.length === 0) {
throw new EmptyResultError('uisdc news', 'UISDC news page loaded, but no news rows with title and URL were extracted.');
}
return rows.slice(0, limit).map((row, index) => ({ ...row, rank: index + 1 }));
}
async function loadUisdcNews(page, args) {
const limit = normalizeLimit(args.limit);
await page.goto(UISDC_NEWS_URL, { waitUntil: 'load', settleMs: 3000 });
const payload = await page.evaluate(buildExtractUisdcNewsJs()).catch((error) => {
throw new CommandExecutionError(`Failed to extract UISDC news: ${getErrorMessage(error)}`);
});
return toRows(payload, limit);
}
export const uisdcNewsCommand = cli({
site: 'uisdc',
name: 'news',
access: 'read',
description: '优设读报 - 最新 AI/设计行业新闻',
domain: 'www.uisdc.com',
strategy: Strategy.PUBLIC,
browser: true,
args: [
{ name: 'limit', type: 'int', default: DEFAULT_LIMIT, help: `Number of news items to return (max ${MAX_LIMIT})` },
],
columns: ['rank', 'title', 'summary', 'url'],
func: loadUisdcNews,
});View on GitHub (pinned to 49907e53dc)
Solutions
- Read the wrapped inner message for the underlying cause
- Retry — transient navigation races often pass on a second attempt
- Increase settleMs or wait for network idle before evaluate to avoid mid-navigation evaluation
- Wrap risky parts of buildExtractUisdcNewsJs in try/catch inside the page script and return {ok:false, reason} instead of throwing
Example fix
// before
return [...document.querySelectorAll('.news-list li')].map(parseRow);
// after
try { return { ok: true, rows: [...document.querySelectorAll('.news-list li')].map(parseRow) }; }
catch (e) { return { ok: false, reason: String(e && e.message || e) }; } Defensive patterns
Strategy: retry
Validate before calling
await page.goto(UISDC_NEWS_URL, { waitUntil: 'load', settleMs: 3000 });
if (page.isClosed() || page.url() !== UISDC_NEWS_URL) throw new Error('page not ready for extraction'); Type guard
function isExtractionFailure(e) { return e instanceof Error && /Failed to extract UISDC news/.test(e.message); } Try / catch
for (let i = 0; i < 3; i++) { try { return await loadUisdcNews(page, args); } catch (e) { if (isExtractionFailure(e) && i < 2) { page = await reopenPage(); continue; } throw e; } } Prevention
- Guard the in-page script body with try/catch returning {ok:false, reason} instead of throwing
- Wait for network idle / a specific selector before evaluate to avoid context-destroyed races
- Avoid navigating or closing the page while evaluate is in flight
- Retry transient failures with a fresh page/context
When it happens
Trigger: The injected script throws a TypeError/ReferenceError inside the page context; page navigation context destroyed mid-evaluate (navigation, tab close, crash); browser/CDP communication failure.
Common situations: Page navigated or redirected while evaluate was running ('Execution context was destroyed'); extension or anti-bot script throwing and breaking the page context; headless browser crash on heavy pages.
Related errors
- Unexpected Boss probe: ${JSON.stringify(probe)}
- Failed to read facebook search results: ${err instanceof Err
- Gemini generation probe failed
- UISDC news page returned an unreadable payload
- UISDC news selector drift: ${reason}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/f69d63b37a95eb13.
Report an issue: GitHub.