fix: catch CircuitOpenError in stats fallback (#10)

This commit is contained in:
Harvey
2026-04-04 15:43:12 +01:00
committed by GitHub
parent c696eae987
commit d2893b93f2
2 changed files with 15 additions and 1 deletions
+2 -1
View File
@@ -15,6 +15,7 @@ from api.v1.schemas.navidrome import (
from core.dependencies import get_navidrome_library_service, get_navidrome_repository
from core.exceptions import ExternalServiceError
from infrastructure.msgspec_fastapi import MsgSpecRoute
from infrastructure.resilience.retry import CircuitOpenError
from repositories.navidrome_repository import NavidromeRepository
from services.navidrome_library_service import NavidromeLibraryService
@@ -50,7 +51,7 @@ async def get_navidrome_albums(
try:
stats = await service.get_stats()
total = stats.total_albums if len(items) >= limit else offset + len(items)
except ExternalServiceError:
except (ExternalServiceError, CircuitOpenError):
logger.warning("Navidrome stats unavailable, using heuristic pagination total")
total = offset + len(items) + (1 if len(items) >= limit else 0)
@@ -19,6 +19,7 @@ from api.v1.schemas.navidrome import (
)
from core.dependencies import get_navidrome_library_service, get_navidrome_playback_service
from core.exceptions import ExternalServiceError
from infrastructure.resilience.retry import CircuitOpenError
def _album_summary(id: str = "a1", name: str = "Album") -> NavidromeAlbumSummary:
@@ -110,6 +111,18 @@ class TestLibraryAlbums:
data = resp.json()
assert data["total"] == 5
def test_get_albums_stats_fallback_circuit_open(self, library_client, mock_library_service):
"""When CB is open, stats raises CircuitOpenError — albums still work."""
mock_library_service.get_albums = AsyncMock(return_value=[_album_summary(id=f"a{i}") for i in range(48)])
mock_library_service.get_stats = AsyncMock(
side_effect=CircuitOpenError("Circuit breaker 'navidrome' is OPEN", breaker_name="navidrome"),
)
resp = library_client.get("/navidrome/albums?limit=48")
assert resp.status_code == 200
data = resp.json()
assert len(data["items"]) == 48
assert data["total"] == 49
def test_get_album_detail(self, library_client):
resp = library_client.get("/navidrome/albums/a1")
assert resp.status_code == 200