From 86ed456682ecd455408b5da3694358f3c5706cc8 Mon Sep 17 00:00:00 2001 From: ogt Date: Fri, 10 Jul 2026 22:06:37 +0800 Subject: [PATCH] fix(api): reject stale alert cache on hard failure --- .../src/services/platform_operator_service.py | 25 ++++++++++--------- .../test_awooop_operator_timeline_labels.py | 8 ++++++ 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/apps/api/src/services/platform_operator_service.py b/apps/api/src/services/platform_operator_service.py index e9871a746..2ca07b034 100644 --- a/apps/api/src/services/platform_operator_service.py +++ b/apps/api/src/services/platform_operator_service.py @@ -1551,19 +1551,20 @@ async def list_ai_alert_card_delivery_readback( summary_row, rows = direct_readback direct_fallback_used = True else: - cached_fallback = await _get_cached_ai_alert_card_delivery_readback( - cache_key=cache_key, - project_id=normalized_project_id, - event_type=normalized_event_type, - lane=normalized_lane, - page=normalized_page, - per_page=normalized_per_page, - ) - if cached_fallback is not None and "learning_registry" in cached_fallback: - return _ai_alert_card_delivery_cached_live_timeout_response( - cached_response=cached_fallback, - error_type=type(exc).__name__, + if isinstance(exc, TimeoutError): + cached_fallback = await _get_cached_ai_alert_card_delivery_readback( + cache_key=cache_key, + project_id=normalized_project_id, + event_type=normalized_event_type, + lane=normalized_lane, + page=normalized_page, + per_page=normalized_per_page, ) + if cached_fallback is not None and "learning_registry" in cached_fallback: + return _ai_alert_card_delivery_cached_live_timeout_response( + cached_response=cached_fallback, + error_type=type(exc).__name__, + ) return _ai_alert_card_delivery_source_unavailable_response( project_id=normalized_project_id, event_type=normalized_event_type or None, diff --git a/apps/api/tests/test_awooop_operator_timeline_labels.py b/apps/api/tests/test_awooop_operator_timeline_labels.py index 987b0d29d..87dab48bf 100644 --- a/apps/api/tests/test_awooop_operator_timeline_labels.py +++ b/apps/api/tests/test_awooop_operator_timeline_labels.py @@ -1302,6 +1302,9 @@ def test_ai_alert_card_source_unavailable_response_exposes_ai_repair_queue() -> async def test_list_ai_alert_card_delivery_readback_failsofts_db_unavailable( monkeypatch: pytest.MonkeyPatch, ) -> None: + async def stale_cache(**_kwargs): + return {"total": 1, "learning_registry": {}} + class FailingDbContext: async def __aenter__(self): raise RuntimeError("db unavailable") @@ -1319,6 +1322,11 @@ async def test_list_ai_alert_card_delivery_readback_failsofts_db_unavailable( "_load_ai_alert_card_delivery_readback_direct", _no_ai_alert_card_direct_readback, ) + monkeypatch.setattr( + platform_operator_service, + "_get_cached_ai_alert_card_delivery_readback", + stale_cache, + ) payload = await platform_operator_service.list_ai_alert_card_delivery_readback( project_id="awoooi",