diff --git a/tests/utils/test_sharepoint_client_error_handling.py b/tests/utils/test_sharepoint_client_error_handling.py index aa52d4bd7..4cae1578e 100644 --- a/tests/utils/test_sharepoint_client_error_handling.py +++ b/tests/utils/test_sharepoint_client_error_handling.py @@ -1,11 +1,16 @@ import logging -from typing import Any, Optional +from typing import Any, Callable, Optional, cast import pytest from utils.sharepoint.sharepoint_client import ( ResourceNotFoundError, - api_call_decorator, + api_call_decorator, # pyright: ignore[reportUnknownVariableType] +) + +# The legacy decorator is untyped; cast so this module stays pyright-strict. +_decorate = cast( + Callable[[Callable[..., Any]], Callable[..., Any]], api_call_decorator ) @@ -26,7 +31,7 @@ class _FakeClient: def is_access_token_expired(self) -> bool: return False - @api_call_decorator + @_decorate def fetch(self, path: str) -> Any: return "GET", f"https://graph.example.invalid/root:/{path}:/children", None @@ -34,9 +39,11 @@ class _FakeClient: def _patch_response( monkeypatch: pytest.MonkeyPatch, response: _FakeResponse ) -> None: + def fake_request(*args: Any, **kwargs: Any) -> _FakeResponse: + return response + monkeypatch.setattr( - "utils.sharepoint.sharepoint_client.requests.request", - lambda *args, **kwargs: response, + "utils.sharepoint.sharepoint_client.requests.request", fake_request ) @@ -56,3 +63,19 @@ def test_404_raises_resource_not_found_without_error_logs( # Assert error_records = [r for r in caplog.records if r.levelno >= logging.ERROR] assert error_records == [] + + +def test_other_client_errors_still_log_at_error_level( + monkeypatch: pytest.MonkeyPatch, caplog: pytest.LogCaptureFixture +) -> None: + # Arrange + _patch_response( + monkeypatch, _FakeResponse(403, "accessDenied", "Access denied.") + ) + + # Act + with pytest.raises(ValueError): + _FakeClient().fetch("forbidden/folder") + + # Assert + assert any(r.levelno >= logging.ERROR for r in caplog.records) diff --git a/utils/sharepoint/sharepoint_client.py b/utils/sharepoint/sharepoint_client.py index 976b47831..0364320f4 100644 --- a/utils/sharepoint/sharepoint_client.py +++ b/utils/sharepoint/sharepoint_client.py @@ -39,6 +39,12 @@ def handle_error(response): inner_error = error_json.get("innererror", {}) details = error_json.get("details", []) + if response.status_code == 404: + logger.debug(f"Not found ({error_code}): {error_message}") + raise ResourceNotFoundError( + f"API request failed with status code 404 - {error_message}" + ) + logger.error(f"Error Code: {error_code}") logger.error(f"Error Message: {error_message}") if inner_error: @@ -50,8 +56,6 @@ def handle_error(response): logger.error("Unauthorized. Token might be invalid.") elif response.status_code == 403: logger.error("Forbidden. Access denied to the requested resource.") - elif response.status_code == 404: - logger.error("Not Found. The requested resource doesn’t exist.") elif response.status_code == 429: retry_after = int( response.headers.get("Retry-After", 5) @@ -125,6 +129,8 @@ def api_call_decorator(func): return response_data + except ResourceNotFoundError: + raise except Exception as e: logger.exception("An error occurred during the API call.") raise e