fix(rss): detect empty or HTML responses feedparser treats as non-bozo (#36) - #69
Conversation
2233admin#36) feedparser reports bozo=False with entries=[] for an empty HTTP 200 body or an HTML error page, making them look like a healthy empty feed (no structured error reaches control, SCHEMA_DRIFT never fires). Fail explicitly with a structured ParseError (maps to SCHEMA_DRIFT in error_kinds.py) when no feed version was detected, on both collect() and fetch() paths. Conservative: a real zero-entry feed still carries a detected version ('rss20'/'atom10') and passes.
|
📋 At a glance Files & modules (2)
✅ Health gate: passed 📌 Before you merge
🔎 More signals (2)🗺️ Change map flowchart LR
subgraph PR ["Changed in this PR (1 with dependents)"]
f_backend_channels_rss_channel_py["backend/channels/rss_channel.py 🔥"]:::changed
end
f_backend_channels_api_channel_py["backend/channels/api_channel.py"]
f_backend_channels_rss_channel_py --> f_backend_channels_api_channel_py
f_backend_channels_registry_py["backend/channels/registry.py"]
f_backend_channels_rss_channel_py --> f_backend_channels_registry_py
f_backend_workflow_rss_source_executor_py["backend/workflow/rss_source_executor.py"]
f_backend_channels_rss_channel_py --> f_backend_workflow_rss_source_executor_py
t_tests_unit_channels_test_rss_channel_py(["✅ .../channels/test_rss_channel.py"]):::guard
t_tests_unit_channels_test_rss_channel_py -.-> f_backend_channels_rss_channel_py
classDef changed fill:#dbeafe,stroke:#1d4ed8,color:#1e3a5f
classDef warn fill:#fef3c7,stroke:#b45309,color:#78350f
classDef guard fill:#dcfce7,stroke:#15803d,color:#14532d
Solid arrows: code that imports the changed files (3 direct dependents, from the last indexed snapshot). Dashed: history/tests. 🔥 Hotspots touched (3)
👀 Suggested reviewers @2233admin 📊 See the full report for this PR |
|
Warning Review limit reached
Next review available in: 59 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Closes #36
问题
feedparser 对空响应体 / HTML 错误页返回
bozo=False, entries=[],与合法空 feed 无法区分(已用 feedparser 6.0.12 实测复现:空 body →bozo=False, version=None;HTML 错误页 →bozo=False, version='')。采集表现为"成功的空 feed",无结构化 error_type 到达 control recorder,SCHEMA_DRIFT 传感器不触发。修复
backend/channels/rss_channel.py:_parsed_version()/_non_feed_response()辅助函数collect()与fetch()在既有 W1 bozo 分支之后,检测"零条目且 feedparser 未识别任何 feed 格式(version 为空/None)"的响应,显式失败并携带error_type="ParseError"(error_kinds.py映射 SCHEMA_DRIFT)version字段作为判据)已在辅助函数 docstring 记录与 WIRING_GAP_LEDGER W1(#35 / #60 已修)互补:W1 覆盖
bozo=True的解析失败,本 PR 覆盖bozo=False的响应质量问题,两者都是 SCHEMA_DRIFT 链路的输入。测试
tests/unit/channels/test_rss_channel_schema_drift.py+4:HTML 错误页 / 空 body / 非 feed 合法 XML →ParseError→SCHEMA_DRIFT;合法空 feed → 成功tests/unit/channels/test_rss_fetch.py+3:fetch 路径 HTML / 空 body →ChannelFetchError(ParseError);合法空 feed → 成功pytest tests/unit/channels/ tests/unit/test_workflow_rss_source_executor.py:285 passedruff check:通过