Implement enhanced error detection for NodeNotFound in OxiAPIError
- Added a new helper function `_looks_like_node_not_found_html` to identify NodeNotFound errors based on HTTP response content. - Updated the `from_http_error` method in the `OxiAPIError` class to convert 500 status codes to 404 when a NodeNotFound error is detected, improving error handling and user feedback.
This commit is contained in:
@@ -13,10 +13,32 @@ _STATUS_MESSAGES: dict[int, str] = {
|
||||
}
|
||||
|
||||
|
||||
def _looks_like_node_not_found_html(e: "HTTPError") -> bool:
|
||||
resp = getattr(e, "response", None)
|
||||
if resp is None:
|
||||
return False
|
||||
try:
|
||||
content_type = (resp.headers or {}).get("Content-Type", "")
|
||||
except Exception:
|
||||
content_type = ""
|
||||
if "text/html" not in (content_type or "").lower():
|
||||
return False
|
||||
try:
|
||||
body = (resp.text or "")[:20_000]
|
||||
except Exception:
|
||||
return False
|
||||
return (
|
||||
"Oxidized::NodeNotFound" in body
|
||||
or "NodeNotFound" in body
|
||||
or "<title>Oxidized::NodeNotFound" in body
|
||||
)
|
||||
|
||||
|
||||
class OxiAPIError(Exception):
|
||||
def __init__(self, message: str, status_code: Optional[int] = None):
|
||||
super().__init__(message)
|
||||
self.status_code = status_code
|
||||
self.message = message
|
||||
|
||||
def __str__(self):
|
||||
if self.status_code is not None:
|
||||
@@ -25,10 +47,19 @@ class OxiAPIError(Exception):
|
||||
|
||||
@classmethod
|
||||
def from_http_error(cls, e: "HTTPError", context: str = "") -> "OxiAPIError":
|
||||
status = e.response.status_code
|
||||
resp = getattr(e, "response", None)
|
||||
status = resp.status_code if resp is not None else None
|
||||
|
||||
if status == 500 and _looks_like_node_not_found_html(e):
|
||||
status = 404
|
||||
|
||||
if status == 404:
|
||||
message = f"{context} not found" if context else "Not found"
|
||||
else:
|
||||
base = _STATUS_MESSAGES.get(status) or e.response.reason or f"HTTP {status}"
|
||||
base = (
|
||||
(_STATUS_MESSAGES.get(status) if status is not None else None)
|
||||
or (resp.reason if resp is not None else None)
|
||||
or (f"HTTP {status}" if status is not None else "Request failed")
|
||||
)
|
||||
message = f"{context}: {base}" if context else base
|
||||
return cls(message, status)
|
||||
|
||||
Reference in New Issue
Block a user