DIYgod/RSSHub · error · Error
Empty content: ${articleUrl}
Error message
Empty content: ${articleUrl} What it means
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.
Source
Thrown at lib/routes/aibase/daily.ts:48
query: {
pagesize: limit,
page: 1,
type: 2,
isen: 0,
},
});
if (!response || !response.data) {
throw new Error('日报数据不存在或为空');
}
const items = await Promise.all(
response.data.slice(0, limit).map(async (item) => {
const articleUrl = `https://www.aibase.com/zh/news/${item.Id}`;
return await cache.tryGet(articleUrl, async () => {
const articleHtml = await ofetch(articleUrl);
const $ = load(articleHtml);
const description = $('.post-content').html();
if (!description) {
throw new Error(`Empty content: ${articleUrl}`);
}
return {
title: item.title,
link: articleUrl,
description,
pubDate: parseDate(item.addtime),
author: 'AI Base',
};
});
})
);
return {
title: 'AI日报',
description: '每天三分钟关注AI行业趋势',
language: 'zh-CN',
link: 'https://www.aibase.com/zh/daily',
item: items,View on GitHub (pinned to bed535e087)
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.
Example fix
// before
const description = $('.post-content').html();
if (!description) throw new Error(`Empty content: ${articleUrl}`);
// after — tolerate missing body, keep the item
const description = $('.post-content').html() || $('.article-content').html() || 'Content unavailable'; Defensive patterns
Strategy: fallback
Validate before calling
function articleHasContent($ /*cheerio root*/) {
return ($.html('.post-content') ?? '').trim().length > 0;
} Type guard
function hasPostContent(html): boolean {
return typeof html === 'string' && html.trim().length > 0;
} Try / catch
try {
return await enrichAibaseArticle(articleUrl);
} catch (e) {
if (e instanceof Error && /Empty content/.test(e.message)) {
// fall back to a title-only item instead of failing the whole daily feed
return { title: item.title, link: articleUrl, description: 'Content unavailable', pubDate: parseDate(item.addtime), author: 'AI Base' };
}
throw e;
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: Site redesign renamed the content class; CDN/WAF challenge on the per-article fetch; article deleted but still listed in the daily index.
Related errors
- 无法获取最新的 year 和 issue
- Category not found
- Tag not found
- Unknown asset type: ${content.assetType} in ${item.link}
- Unknown placeholder type: ${placeholder?.type} in ${link}
AI-assisted analysis of DIYgod/RSSHub@bed535e087 (2026-08-12).
Data as JSON: /api/errors/c761dd79c5f4f766.
Report an issue: GitHub.