diff --git a/backend/src/media_library_viewer_api/dependencies.py b/backend/src/media_library_viewer_api/dependencies.py index ed390a4..ef00d8b 100644 --- a/backend/src/media_library_viewer_api/dependencies.py +++ b/backend/src/media_library_viewer_api/dependencies.py @@ -163,11 +163,17 @@ def get_jellyfin_client(request: Request = None) -> JellyfinClient: service_id = _request_jellyfin_service_id(request) service = _service_record(store, "jellyfin", service_id) if service is None: - raise RuntimeError("No Jellyfin service is configured. Add a Jellyfin service on the Services page.") + raise HTTPException( + status_code=503, + detail="No Jellyfin service is configured. Add a Jellyfin service on the Services page.", + ) base_url = str(service.get("config", {}).get("base_url") or "") api_key = str(service.get("secrets", {}).get("api_key") or "") if not base_url or not api_key: - raise RuntimeError("Jellyfin service is missing base_url or api_key. Edit it on the Services page.") + raise HTTPException( + status_code=503, + detail="Jellyfin service is missing base_url or api_key. Edit it on the Services page.", + ) cache_key = (service["id"], base_url, api_key) return _jellyfin_client_for(cache_key) @@ -244,7 +250,10 @@ def get_ssh_client(request: Request = None): "set" if settings.ssh_password else "missing", ) if not settings.ssh_key_path: - raise RuntimeError("No SSH machine is configured and SSH key settings must be configured") + raise HTTPException( + status_code=503, + detail="No SSH machine is configured and SSH key settings must be configured", + ) return _ssh_client_for( ( "legacy", @@ -280,5 +289,8 @@ def get_user_id(request: Request = None) -> str: client = get_jellyfin_client(request) users = client.users() if not users: - raise RuntimeError("No Jellyfin users found and no user_id configured on the service") + raise HTTPException( + status_code=503, + detail="No Jellyfin users found and no user_id configured on the service", + ) return users[0]["Id"] diff --git a/backend/tests/test_api.py b/backend/tests/test_api.py index e2056f7..c986952 100644 --- a/backend/tests/test_api.py +++ b/backend/tests/test_api.py @@ -211,6 +211,22 @@ class TestDashboard: data = response.json() assert len(data) == 2 + def test_jellyfin_endpoints_return_503_when_not_configured(self, test_client): + # Remove the mocked Jellyfin dependency so the real one runs; with no + # Jellyfin service seeded, endpoints must degrade to 503, not 500. + app.dependency_overrides.pop(get_jellyfin_client, None) + app.dependency_overrides.pop(get_user_id, None) + try: + for path in ("/api/dashboard/counts", "/api/dashboard/activity"): + response = test_client.get(path) + assert response.status_code == 503, path + detail = response.json()["detail"] + assert "configured" in detail, path + finally: + # Restore the mocks for subsequent tests in this fixture session. + app.dependency_overrides[get_jellyfin_client] = lambda: MagicMock() + app.dependency_overrides[get_user_id] = lambda: "user123" + # --- Settings reset ---