sansan0/TrendRadar · error · DataNotFoundError
DATA_NOT_FOUND
DATA_NOT_FOUND
Error message
未找到 {date_str} 的 {db_type} 数据 What it means
After feedparser.parse() runs, the code checks feed.bozo (feedparser's 'malformed feed' flag). If bozo is set AND there are zero entries, the feed is considered unparseable and ValueError is raised with feed.bozo_exception (the underlying parse error such as an XML syntax error or a content-type mismatch). If bozo is set but entries were still recovered, parsing continues — this error means the feed was truly unusable.
Source
Thrown at mcp_server/services/parser_service.py:343
DataNotFoundError: 数据不存在
"""
date_str = self.get_date_folder_name(date)
platform_key = ','.join(sorted(platform_ids)) if platform_ids else 'all'
cache_key = f"read_all:{db_type}:{date_str}:{platform_key}"
is_today = (date is None) or (date.date() == datetime.now().date())
ttl = 900 if is_today else 900
cached = self.cache.get(cache_key, ttl=ttl)
if cached:
return cached
result = self._read_from_sqlite(date, platform_ids, db_type)
if result:
self.cache.set(cache_key, result)
return result
raise DataNotFoundError(
f"未找到 {date_str} 的 {db_type} 数据",
suggestion="请先运行爬虫或检查日期是否正确"
)
def parse_yaml_config(self, config_path: str = None) -> dict:
"""
解析YAML配置文件
Args:
config_path: 配置文件路径,默认为 config/config.yaml
Returns:
配置字典
Raises:
FileParseError: 配置文件解析错误
"""
if config_path is None:View on GitHub (pinned to 8ee26026ba)
Solutions
- Log the full bozo_exception and fetch_url content-type/body snippet — 'Not a valid feed' vs 'XML syntax error' vs 'document declared as ... but parsed as ...' point to HTML-response, truncation, and encoding respectively.
- Verify the URL still serves XML: curl -L -H 'Accept: application/rss+xml' <feed_url> | head. If it is an HTML challenge page, add proper headers/cookies or replace the feed URL with its real syndication address.
- If the body was fetched upstream, ensure HTTP errors raise and the raw (non-decoded, correctly charset-handled) text is passed through unchanged to parse().
- Treat this as per-feed failure in multi-feed monitoring: catch the ValueError, mark the feed unhealthy, and keep polling others instead of letting one bad feed kill the run.
Example fix
# before
feed = feedparser.parse(content)
if feed.bozo and not feed.entries:
raise ValueError(f"RSS 解析失败 ({feed_url}): {feed.bozo_exception}")
# after: caller isolates per-feed failures
try:
items = parser.parse(content, feed_url)
except ValueError as e:
logger.error("skipping feed %s: %s", feed_url, e)
items = [] Defensive patterns
Strategy: try-catch
Validate before calling
def looks_like_feed(content: str) -> bool:
"""Cheap sniff before full parse: XML or JSON feed markers."""
head = content.lstrip()[:200].lower()
return (
head.startswith("<?xml")
or "<rss" in head
or "<feed" in head
or head.startswith("{")
) Try / catch
for feed_url, content in feeds:
try:
items = parser.parse(content, feed_url)
except ValueError as e:
logger.error("unhealthy feed %s: %s", feed_url, e)
mark_feed_unhealthy(feed_url) # keep other feeds running
continue Prevention
- Fetch with raise_for_status and pass the raw, unmodified body to parse() so HTML error pages never reach feedparser.
- Track per-feed consecutive-failure counts and alert after N failures instead of reacting to each parse error.
- Log feed.bozo_exception verbatim — it distinguishes HTML-page, truncation, and encoding causes immediately.
When it happens
Trigger: Calling RSSParser.parse(content, feed_url) with: non-XML content (an HTML login/error page from behind a CDN or paywall), truncated XML (connection cut mid-download, proxy returning partial body), wrong encoding declared in the XML declaration, or an empty string. Each produces bozo=True with zero entries and raises with the specific bozo_exception.
Common situations: Feed URL now returns an HTML consent/anti-bot page (Cloudflare, cookie wall) so the fetched 'XML' is actually HTML; feed moved or dead returning a 404 HTML page fetched without raise_for_status; saving response bytes with the wrong charset; a proxy mangling/gzipping the body; hand-testing parse() with a snippet instead of the full document.
Related errors
AI-assisted analysis of sansan0/TrendRadar@8ee26026ba (2026-08-15).
Data as JSON: /api/errors/15f5cef37f482cc6.
Report an issue: GitHub.