{"record":{"id":"b31e23faa212c814","repo":"jackwener/OpenCLI","slug":"browser-page-required-b31e23","errorCode":null,"errorMessage":"Browser page required","messagePattern":"Browser page required","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/v2ex/notifications.js","lineNumber":20,"sourceCode":" * V2EX Notifications adapter.\n */\nimport { CommandExecutionError } from '@jackwener/opencli/errors';\nimport { cli, Strategy } from '@jackwener/opencli/registry';\ncli({\n    site: 'v2ex',\n    name: 'notifications',\n    access: 'read',\n    description: 'V2EX 获取提醒 (回复/由于)',\n    domain: 'www.v2ex.com',\n    strategy: Strategy.COOKIE,\n    browser: true,\n    args: [\n        { name: 'limit', type: 'int', default: 20, help: 'Number of notifications' }\n    ],\n    columns: ['type', 'content', 'time'],\n    func: async (page, kwargs) => {\n        if (!page)\n            throw new CommandExecutionError('Browser page required');\n        if (process.env.OPENCLI_VERBOSE) {\n            console.error('[opencli:v2ex] Navigating to /notifications');\n        }\n        await page.goto('https://www.v2ex.com/notifications');\n        await new Promise(r => setTimeout(r, 1500)); // waitForLoadState doesn't always work robustly\n        // Evaluate DOM to extract notifications\n        const data = await page.evaluate(`\n      async () => {\n        const items = Array.from(document.querySelectorAll('#Main .box .cell[id^=\"n_\"]'));\n        return items.map(item => {\n          let type = '通知';\n          let time = '';\n          \n          // determine type based on text content\n          const text = item.textContent || '';\n          if (text.includes('回复了你')) type = '回复';\n          else if (text.includes('感谢了你')) type = '感谢';\n          else if (text.includes('收藏了你')) type = '收藏';","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/v2ex/notifications.js#L2-L38","documentation":"The v2ex notifications command (browser:true, Strategy.COOKIE) throws CommandExecutionError('Browser page required') when func receives a falsy page. Like the other v2ex browser commands, it guards against calling page.goto on null when the browser layer failed to provision a page.","triggerScenarios":"Calling the v2ex notifications command when no browser page was supplied — browser launch failure, missing browser binary, or direct invocation of func without a page.","commonSituations":"Chromium/playwright not installed in a headless CI environment; browser user-data-dir locked; registry bypassed by calling the command function directly in tests or scripts.","solutions":["Install or repair the browser runtime (e.g. playwright install chromium) plus system dependencies.","Run the command through the opencli CLI so a page is provisioned automatically.","Inspect earlier logs for the actual browser-launch failure (missing binary, profile lock) and fix it.","In programmatic use, pass a valid live page object to func rather than null/undefined."],"exampleFix":"// before\nawait notificationsFunc(null, { limit: 20 });\n// after: invoke via CLI/registry\n// $ opencli v2ex notifications --limit 20","handlingStrategy":"validation","validationCode":"if (!page || typeof page.goto !== 'function') {\n  throw new Error('Browser page unavailable — install browser runtime and run through the CLI');\n}","typeGuard":"function hasPage(p) {\n  return !!p && typeof p === 'object' && typeof p.goto === 'function' && typeof p.evaluate === 'function';\n}","tryCatchPattern":"try {\n  await runNotifications({ limit: 20 });\n} catch (e) {\n  if (e.message === 'Browser page required') {\n    // fix browser provisioning, then retry\n  } else throw e;\n}","preventionTips":["Install/repair the browser runtime before headless runs (playwright install chromium + deps).","Call commands via the CLI/registry so the page argument is always provided.","Guard programmatic tests with a page fixture instead of passing null.","Watch for browser launch failures in earlier logs; this error is usually downstream of those."],"tags":["browser","environment","null-check"],"backgroundTag":"browser-page-not-available","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}