mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-12 13:29:04 +00:00
SharePoint 404s raise ResourceNotFoundError without error-level logging 🟩
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
4a71c555fa
commit
dc188ca3c5
2 changed files with 36 additions and 7 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue