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

  1. Read the wrapped inner message for the underlying cause
  2. Retry — transient navigation races often pass on a second attempt
  3. Increase settleMs or wait for network idle before evaluate to avoid mid-navigation evaluation
  4. 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

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


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