{"record":{"id":"3b7029b40842bc40","repo":"jackwener/OpenCLI","slug":"url-must-be-on-reuters-com-got-url","errorCode":null,"errorMessage":"URL must be on reuters.com, got ${url}","messagePattern":"URL must be on reuters\\.com, got (.+?)","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/reuters/article-detail.js","lineNumber":30,"sourceCode":"\ncli({\n    site: 'reuters',\n    name: 'article-detail',\n    access: 'read',\n    description: 'Reuters 路透社文章详情：标题/作者/正文文本',\n    domain: 'www.reuters.com',\n    strategy: Strategy.COOKIE,\n    args: [\n        { name: 'url', required: true, positional: true, help: 'Reuters article URL (must be on reuters.com)' },\n    ],\n    columns: ['title', 'date', 'section', 'section_path', 'authors', 'description', 'word_count', 'url', 'body'],\n    func: async (page, kwargs) => {\n        const url = String(kwargs.url || '').trim();\n        if (!url) {\n            throw new ArgumentError('Article URL cannot be empty');\n        }\n        if (!REUTERS_HOST.test(url)) {\n            throw new ArgumentError(`URL must be on reuters.com, got ${url}`);\n        }\n        await page.goto(url);\n        await page.wait(2);\n        const result = await page.evaluate(buildArticleDetailScript());\n        if (result?.error) {\n            throw new CommandExecutionError(`Reuters article-detail failed inside the page: ${result.error}`);\n        }\n        if (result?.authRequired) {\n            throw new AuthRequiredError('www.reuters.com', 'Reuters article-detail is gated by login, subscription, or human verification');\n        }\n        if (!result || result.ok !== true) {\n            throw new CommandExecutionError(\n                'Reuters article-detail returned no payload',\n                'Check that the URL points to a Reuters article and that the page loaded',\n            );\n        }\n        const detail = mapArticleDetail(result.body?.article, result.body?.bodyText, url);\n        if (!detail || (!detail.title && !detail.body)) {","sourceCodeStart":12,"sourceCodeEnd":48,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/reuters/article-detail.js#L12-L48","documentation":"The reuters article-detail command throws ArgumentError when the supplied URL does not match REUTERS_HOST, i.e. it is not a reuters.com URL. The command scrapes Reuters pages and only supports reuters.com, so off-site URLs are rejected up front.","triggerScenarios":"Passing a URL on another domain (e.g. reuters.org, a Google News redirect, an archive mirror) or a misspelled host, so the REUTERS_HOST regex test fails.","commonSituations":"Using a shortened or redirected link that resolves off reuters.com; copying an AMP or third-party syndicated copy of the article; typos like 'reuterss.com'; passing a search-results page from another site.","solutions":["Use the canonical www.reuters.com article URL","Resolve shorteners/redirects to their final reuters.com destination first","Check the URL for typos in the hostname","If the article only exists off-site, this command cannot fetch it — use a source-appropriate tool"],"exampleFix":"// before\nreuters article-detail \"https://news.google.com/rss/articles/CBM...\"\n// after\nreuters article-detail \"https://www.reuters.com/world/us/some-article-2026-01-01/\"","handlingStrategy":"validation","validationCode":"try {\n  const u = new URL(input);\n  if (!/(^|\\.)reuters\\.com$/.test(u.hostname)) throw new Error('not a reuters.com URL: ' + input);\n} catch { throw new Error('invalid URL: ' + input); }","typeGuard":"function isReutersUrl(u) {\n  try { return new URL(u).hostname.endsWith('reuters.com'); } catch { return false; }\n}","tryCatchPattern":"null","preventionTips":["Resolve redirects/shorteners to the canonical reuters.com URL before calling","Validate hostname with new URL(), not string contains","Watch for AMP or syndicated copies on other domains","Unit-test URL validation in wrapper scripts"],"tags":["validation","argument-error","url"],"backgroundTag":"invalid-url-host","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}