{"record":{"id":"c761dd79c5f4f766","repo":"DIYgod/RSSHub","slug":"empty-content-articleurl","errorCode":null,"errorMessage":"Empty content: ${articleUrl}","messagePattern":"Empty content: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":503,"severity":"error","filePath":"lib/routes/aibase/daily.ts","lineNumber":48,"sourceCode":"            query: {\n                pagesize: limit,\n                page: 1,\n                type: 2,\n                isen: 0,\n            },\n        });\n        if (!response || !response.data) {\n            throw new Error('日报数据不存在或为空');\n        }\n        const items = await Promise.all(\n            response.data.slice(0, limit).map(async (item) => {\n                const articleUrl = `https://www.aibase.com/zh/news/${item.Id}`;\n                return await cache.tryGet(articleUrl, async () => {\n                    const articleHtml = await ofetch(articleUrl);\n                    const $ = load(articleHtml);\n                    const description = $('.post-content').html();\n                    if (!description) {\n                        throw new Error(`Empty content: ${articleUrl}`);\n                    }\n                    return {\n                        title: item.title,\n                        link: articleUrl,\n                        description,\n                        pubDate: parseDate(item.addtime),\n                        author: 'AI Base',\n                    };\n                });\n            })\n        );\n\n        return {\n            title: 'AI日报',\n            description: '每天三分钟关注AI行业趋势',\n            language: 'zh-CN',\n            link: 'https://www.aibase.com/zh/daily',\n            item: items,","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/DIYgod/RSSHub/blob/bed535e0879dc71c5aff6f1e7bd1ac21ede40115/lib/routes/aibase/daily.ts#L30-L66","documentation":"For each AI Base news item the route fetches the article HTML and reads the `.post-content` selector. If that selector yields no HTML (empty string), it throws a generic `Error('Empty content: <url>')`. Because this runs inside cache.tryGet, the failure (and any partial state) is not cached, but the whole feed fails.","triggerScenarios":"The article page changed markup so `.post-content` no longer matches; the article is paywalled/removed; an anti-bot interstitial was returned instead of the article.","commonSituations":"Site redesign renamed the content class; CDN/WAF challenge on the per-article fetch; article deleted but still listed in the daily index.","solutions":["Open the failing articleUrl in a browser to confirm the markup.","If the selector changed, update '.post-content' to the new class as a maintainer.","Retry later for transient blocks; consider degrading to a title-only item instead of throwing."],"exampleFix":"// before\nconst description = $('.post-content').html();\nif (!description) throw new Error(`Empty content: ${articleUrl}`);\n// after — tolerate missing body, keep the item\nconst description = $('.post-content').html() || $('.article-content').html() || 'Content unavailable';","handlingStrategy":"fallback","validationCode":"function articleHasContent($ /*cheerio root*/) {\n  return ($.html('.post-content') ?? '').trim().length > 0;\n}","typeGuard":"function hasPostContent(html): boolean {\n  return typeof html === 'string' && html.trim().length > 0;\n}","tryCatchPattern":"try {\n  return await enrichAibaseArticle(articleUrl);\n} catch (e) {\n  if (e instanceof Error && /Empty content/.test(e.message)) {\n    // fall back to a title-only item instead of failing the whole daily feed\n    return { title: item.title, link: articleUrl, description: 'Content unavailable', pubDate: parseDate(item.addtime), author: 'AI Base' };\n  }\n  throw e;\n}","preventionTips":["Treat empty `.post-content` as a markup-change signal — verify in a browser.","Consider degrading to a title-only item rather than throwing inside Promise.all (one bad article shouldn't kill the feed).","Watch for WAF interstitials on per-article fetches."],"tags":["upstream-dependent","selector","scraping","rsshub","error-class-mismatch"],"backgroundTag":null,"analyzedSha":"bed535e0879dc71c5aff6f1e7bd1ac21ede40115","analyzedAt":"2026-08-12T19:29:35.364Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}