fix(api): degrade recent event readback failures
All checks were successful
CD Pipeline / workflow-shape (push) Successful in 1s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m26s
CD Pipeline / build-and-deploy (push) Successful in 4m41s
CD Pipeline / post-deploy-checks (push) Successful in 4m49s
All checks were successful
CD Pipeline / workflow-shape (push) Successful in 1s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 2m26s
CD Pipeline / build-and-deploy (push) Successful in 4m41s
CD Pipeline / post-deploy-checks (push) Successful in 4m49s
This commit is contained in:
@@ -118,6 +118,8 @@ class RecentEventsResponse(BaseModel):
|
|||||||
events: list[ChannelEventItem]
|
events: list[ChannelEventItem]
|
||||||
total: int
|
total: int
|
||||||
limit: int
|
limit: int
|
||||||
|
source_status: str = "ready"
|
||||||
|
source_error: str | None = None
|
||||||
|
|
||||||
|
|
||||||
class ChannelEventDossierItem(BaseModel):
|
class ChannelEventDossierItem(BaseModel):
|
||||||
@@ -667,9 +669,26 @@ async def list_recent_events(
|
|||||||
),
|
),
|
||||||
limit: int = Query(20, ge=1, le=100, description="最多返回筆數"),
|
limit: int = Query(20, ge=1, le=100, description="最多返回筆數"),
|
||||||
) -> dict[str, Any]:
|
) -> dict[str, Any]:
|
||||||
return await list_recent_channel_events(
|
try:
|
||||||
project_id=project_id,
|
return await list_recent_channel_events(
|
||||||
channel_type=channel_type,
|
project_id=project_id,
|
||||||
provider_prefix=provider_prefix,
|
channel_type=channel_type,
|
||||||
limit=limit,
|
provider_prefix=provider_prefix,
|
||||||
)
|
limit=limit,
|
||||||
|
)
|
||||||
|
except Exception as exc:
|
||||||
|
logger.warning(
|
||||||
|
"recent_channel_events_source_unavailable",
|
||||||
|
project_id=project_id or "awoooi",
|
||||||
|
channel_type=channel_type,
|
||||||
|
provider_prefix=provider_prefix,
|
||||||
|
limit=limit,
|
||||||
|
error=exc.__class__.__name__,
|
||||||
|
)
|
||||||
|
return {
|
||||||
|
"events": [],
|
||||||
|
"total": 0,
|
||||||
|
"limit": max(1, min(limit, 100)),
|
||||||
|
"source_status": "source_unavailable",
|
||||||
|
"source_error": exc.__class__.__name__,
|
||||||
|
}
|
||||||
|
|||||||
@@ -10,6 +10,33 @@ from src.core.context import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.asyncio
|
||||||
|
async def test_recent_events_degrades_when_source_unavailable(monkeypatch):
|
||||||
|
async def fake_list_recent_channel_events(**kwargs):
|
||||||
|
raise RuntimeError("db unavailable")
|
||||||
|
|
||||||
|
monkeypatch.setattr(
|
||||||
|
events,
|
||||||
|
"list_recent_channel_events",
|
||||||
|
fake_list_recent_channel_events,
|
||||||
|
)
|
||||||
|
|
||||||
|
response = await events.list_recent_events(
|
||||||
|
project_id="awoooi",
|
||||||
|
channel_type=None,
|
||||||
|
provider_prefix="alertmanager",
|
||||||
|
limit=20,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert response == {
|
||||||
|
"events": [],
|
||||||
|
"total": 0,
|
||||||
|
"limit": 20,
|
||||||
|
"source_status": "source_unavailable",
|
||||||
|
"source_error": "RuntimeError",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.asyncio
|
@pytest.mark.asyncio
|
||||||
async def test_source_correlation_review_uses_body_project_context(monkeypatch):
|
async def test_source_correlation_review_uses_body_project_context(monkeypatch):
|
||||||
observed: dict[str, object] = {}
|
observed: dict[str, object] = {}
|
||||||
|
|||||||
Reference in New Issue
Block a user