Problem
Two freshness gaps in get_and_clean_feed (src/rss.py:18-61):
-
Silent staleness: feedparser.parse(url) never raises on HTTP/network errors — it returns a "bozo" feed with no entries. The function then hits if not feed.entries: return (src/rss.py:21-22) and keeps the previous artifact's cached file. That's the intended cache behavior, but nothing is logged, so a feed that has been failing for weeks is indistinguishable from a healthy one without manually diffing the deployed XML. There is no feed.bozo / status check anywhere.
-
Empty-feed overwrite: if the fetch succeeds but every entry fails per-entry parsing (e.g. an upstream date-format change — both strptime formats at src/rss.py:45-47 raise, each exception is caught and only logged), the loop appends zero items and new_feed.write still overwrites the previously good cached XML with an empty feed (src/rss.py:60-61). The failure mode thus destroys the cached data instead of preserving it.
Related: the workflow's verification step (.github/workflows/build.yml:72-77) checks only the SQLite snapshots and schemas; RSS outputs are never verified, so case 2 deploys unnoticed.
Suggested fix
- Log a warning when
feed.bozo is set or feed.entries is empty, e.g. ::warning:: so it surfaces in the Actions summary.
- Skip writing (keep the cached file) when entries were fetched but zero items survived parsing.
- Optionally extend the verify step to check that
build/rss/*.xml exists and is non-empty.
Problem
Two freshness gaps in
get_and_clean_feed(src/rss.py:18-61):Silent staleness:
feedparser.parse(url)never raises on HTTP/network errors — it returns a "bozo" feed with no entries. The function then hitsif not feed.entries: return(src/rss.py:21-22) and keeps the previous artifact's cached file. That's the intended cache behavior, but nothing is logged, so a feed that has been failing for weeks is indistinguishable from a healthy one without manually diffing the deployed XML. There is nofeed.bozo/ status check anywhere.Empty-feed overwrite: if the fetch succeeds but every entry fails per-entry parsing (e.g. an upstream date-format change — both
strptimeformats at src/rss.py:45-47 raise, each exception is caught and only logged), the loop appends zero items andnew_feed.writestill overwrites the previously good cached XML with an empty feed (src/rss.py:60-61). The failure mode thus destroys the cached data instead of preserving it.Related: the workflow's verification step (
.github/workflows/build.yml:72-77) checks only the SQLite snapshots and schemas; RSS outputs are never verified, so case 2 deploys unnoticed.Suggested fix
feed.bozois set orfeed.entriesis empty, e.g.::warning::so it surfaces in the Actions summary.build/rss/*.xmlexists and is non-empty.