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

  1. 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.
  2. 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.
  3. 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().
  4. 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

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.