diff --git a/pageindex/backend/cloud.py b/pageindex/backend/cloud.py index f7462d4..09f095b 100644 --- a/pageindex/backend/cloud.py +++ b/pageindex/backend/cloud.py @@ -173,7 +173,13 @@ class CloudBackend: return None def list_collections(self) -> list[str]: - data = self._request("GET", "/folders/") + try: + data = self._request("GET", "/folders/") + except CloudAPIError as e: + if e.status_code in self._FOLDER_UNAVAILABLE: + self._warn_folder_upgrade() + return [] + raise return [f["name"] for f in data.get("folders", []) or []] def delete_collection(self, name: str) -> None: diff --git a/tests/test_cloud_backend.py b/tests/test_cloud_backend.py index 16dce98..6154473 100644 --- a/tests/test_cloud_backend.py +++ b/tests/test_cloud_backend.py @@ -127,6 +127,28 @@ def test_folder_transient_error_propagates_and_is_not_cached(monkeypatch): assert "col" not in backend._folder_id_cache +def test_list_collections_degrades_when_folders_unavailable(monkeypatch): + backend = CloudBackend(api_key="pi-test") + + def fake_request(method, path, **kwargs): + raise CloudAPIError("Cloud API error 403: upgrade", status_code=403) + + monkeypatch.setattr(backend, "_request", fake_request) + with pytest.warns(UserWarning, match="not available on this plan"): + assert backend.list_collections() == [] + + +def test_list_collections_propagates_transient_error(monkeypatch): + backend = CloudBackend(api_key="pi-test") + + def fake_request(method, path, **kwargs): + raise CloudAPIError("Cloud API error 503: unavailable", status_code=503) + + monkeypatch.setattr(backend, "_request", fake_request) + with pytest.raises(CloudAPIError): + backend.list_collections() + + # ── doc endpoints: 404 maps to DocumentNotFoundError (local parity) ────────── def test_doc_404_maps_to_document_not_found(monkeypatch):