Fix RSS/Atom feed errors appearing as new entries on every poll#667
Fix RSS/Atom feed errors appearing as new entries on every poll#667
Conversation
When an RSS/Atom feed health check detects an incident, the resulting ServiceWarning now carries the most recent incident's publish date as its timestamp. The feed renderer uses that timestamp (falling back to the current time) so feed readers don't treat the same incident as a new entry on every poll. Co-authored-by: codingjoe <1772890+codingjoe@users.noreply.github.com>
… in rss.py, add Atlassian timestamp support - Add StatusPageWarning(ServiceWarning) exception type carrying an optional source timestamp, instead of adding timestamp to the base HealthCheckException - Fix rss.py double-loop: _recent_incidents() generator calls _extract_date() once per entry, yielding (entry, date) pairs; run() consumes these to build both the message and max timestamp in a single pass - Atlassian: _fetch_incidents() yields (message, timestamp) tuples via new _parse_incident_timestamp(); run() raises StatusPageWarning with the most recent incident timestamp - views.py uses getattr(result.error, 'timestamp', None) for safety - Update all tests to use StatusPageWarning; add Atlassian timestamp propagation test Co-authored-by: codingjoe <1772890+codingjoe@users.noreply.github.com>
Done in 3c003ed. |
|
pre-commit.ci run |
for more information, see https://pre-commit.ci
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #667 +/- ##
=======================================
Coverage 99.73% 99.74%
=======================================
Files 13 13
Lines 768 772 +4
=======================================
+ Hits 766 770 +4
Misses 2 2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
codingjoe
left a comment
There was a problem hiding this comment.
@copilot atlassian.py L93 isn't covered yet.
Please add the optional timestamp to the base exception, to avoid the getattr(), but keep the specific implementation for Atom/RSS incidents. default to timezone.now() if no time was passed.
- HealthCheckException now accepts optional `timestamp` kwarg defaulting to datetime.datetime.now(tz=utc) so every error always carries a timestamp - views.py can now use result.error.timestamp directly (no getattr), and the unused django.utils.timezone import is removed - StatusPageWarning simplified to just super().__init__(message, timestamp=timestamp) - Add test_check_status__incident_with_invalid_timestamp in TestFlyIo to cover the except ValueError branch in _parse_incident_timestamp (atlassian.py L93) - Update exception tests: timestamp defaults to now, not None Co-authored-by: codingjoe <1772890+codingjoe@users.noreply.github.com>
Done in 64e3e10:
|
…atusPageWarning.__init__ - Replace bare `datetime.datetime.now(tz=utc)` with `timezone.now()` in HealthCheckException as requested - Remove the redundant __init__ override in StatusPageWarning — it inherits the timestamp kwarg directly from HealthCheckException - Update tests to use timezone.now() for timestamp-default assertions Co-authored-by: codingjoe <1772890+codingjoe@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR fixes RSS/Atom feeds repeatedly surfacing the same upstream status-page incident as a “new” entry on every poll by propagating the incident’s source timestamp through health check exceptions into feed rendering.
Changes:
- Add a
timestampattribute toHealthCheckException(defaulting totimezone.now()), plus aStatusPageWarningtype for status-page sourced warnings. - Update RSS and Atlassian status-page checks to raise
StatusPageWarningwith the most recent incident timestamp. - Update feed rendering and tests to ensure RSS/Atom items use the exception timestamp instead of “current time”.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
health_check/exceptions.py |
Adds timestamp support on HealthCheckException and introduces StatusPageWarning. |
health_check/views.py |
Uses result.error.timestamp for RSS/Atom pubdate/updateddate. |
health_check/contrib/rss.py |
Raises StatusPageWarning with max incident date; refactors recent-incident iteration. |
health_check/contrib/atlassian.py |
Parses incident timestamps and raises StatusPageWarning with the most recent timestamp. |
tests/test_exceptions.py |
Adds unit tests for exception timestamp defaulting/storage and StatusPageWarning behavior. |
tests/test_views.py |
Adds regression tests asserting feed dates come from exception timestamps when provided. |
tests/contrib/test_rss.py |
Verifies RSS incident warnings carry the most recent source pubDate timestamp. |
tests/contrib/test_atlassian.py |
Verifies Atlassian incident warnings carry source timestamps and covers invalid timestamp parsing. |
codingjoe
left a comment
There was a problem hiding this comment.
@copilot This code is too defensive. The atlassian API is stable. If you don't know the response data structure fetch the spec here: https://status.atlassian.com/api
… resolved incidents - exceptions.py: use explicit None check for timestamp default to avoid masking falsy-but-valid datetime values - atlassian.py: drop _parse_incident_timestamp helper; use updated_at directly (always present per API spec); filter out resolved and postmortem incidents - tests: update incident fixtures with status/updated_at, replace invalid-timestamp test with test_check_status__resolved_incidents_are_filtered Co-authored-by: codingjoe <1772890+codingjoe@users.noreply.github.com>
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
Feed error entries used
timezone.now()as their publish date, causing feed readers to flag the same incident as new on every poll. For proxied status pages (AWS, GCP, Atlassian-based, etc.), the incident date from the source feed is now preserved.Changes
HealthCheckException: Added an optionaltimestampkwarg (defaulting totimezone.now()via an explicitNonecheck) so every error always carries a timestamp and feed rendering can useresult.error.timestampdirectly.StatusPageWarning: NewStatusPageWarning(ServiceWarning)exception type for RSS/Atom and Atlassian status-page incidents. Inherits thetimestampkwarg fromHealthCheckExceptionwithout overriding__init__.contrib/rss.py: Introduced_recent_incidents()generator that calls_extract_date()once per entry (fixing a previous double-loop) and yields(entry, date)pairs. The most recent incident date is passed astimestamptoStatusPageWarning.contrib/atlassian.py:_fetch_incidents()usesincident["updated_at"]directly (per the Atlassian Status Page API spec) and filters out incidents withstatusof"resolved"or"postmortem". The defensive_parse_incident_timestamphelper and itstry/exceptare removed.views.py:_render_feedusesresult.error.timestampdirectly — the timestamp is always set on every error, defaulting to current time for generic errors and carrying the source incident date for status-page warnings.Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.