Spaces:
Running
Running
Add detailed error mapping debug logs.
Browse filesWill show exact exception type and mapping path.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- providers/error_mapping.py +19 -0
providers/error_mapping.py
CHANGED
|
@@ -38,39 +38,58 @@ def map_error(
|
|
| 38 |
so reactive 429 handling applies to the correct provider. Tests may omit
|
| 39 |
``rate_limiter`` to use the process-wide singleton.
|
| 40 |
"""
|
|
|
|
|
|
|
| 41 |
message = get_user_facing_error_message(e)
|
|
|
|
|
|
|
|
|
|
| 42 |
limiter = rate_limiter or GlobalRateLimiter.get_instance()
|
| 43 |
|
| 44 |
if isinstance(e, openai.AuthenticationError):
|
|
|
|
| 45 |
return AuthenticationError(message, raw_error=str(e))
|
| 46 |
if isinstance(e, openai.RateLimitError):
|
| 47 |
limiter.set_blocked(60)
|
|
|
|
| 48 |
return RateLimitError(message, raw_error=str(e))
|
| 49 |
if isinstance(e, openai.BadRequestError):
|
|
|
|
| 50 |
return InvalidRequestError(message, raw_error=str(e))
|
| 51 |
if isinstance(e, openai.InternalServerError):
|
| 52 |
raw_message = str(e)
|
| 53 |
if "overloaded" in raw_message.lower() or "capacity" in raw_message.lower():
|
|
|
|
| 54 |
return OverloadedError(message, raw_error=raw_message)
|
|
|
|
| 55 |
return APIError(message, status_code=500, raw_error=str(e))
|
| 56 |
if isinstance(e, openai.APIError):
|
|
|
|
| 57 |
return APIError(
|
| 58 |
message, status_code=getattr(e, "status_code", 500), raw_error=str(e)
|
| 59 |
)
|
| 60 |
|
| 61 |
if isinstance(e, httpx.HTTPStatusError):
|
| 62 |
status = e.response.status_code
|
|
|
|
| 63 |
if status in (401, 403):
|
|
|
|
| 64 |
return AuthenticationError(message, raw_error=str(e))
|
| 65 |
if status == 429:
|
| 66 |
limiter.set_blocked(60)
|
|
|
|
| 67 |
return RateLimitError(message, raw_error=str(e))
|
| 68 |
if status == 400:
|
|
|
|
| 69 |
return InvalidRequestError(message, raw_error=str(e))
|
| 70 |
if status >= 500:
|
| 71 |
if status in (502, 503, 504):
|
|
|
|
| 72 |
return OverloadedError(message, raw_error=str(e))
|
|
|
|
| 73 |
return APIError(message, status_code=status, raw_error=str(e))
|
|
|
|
| 74 |
return APIError(message, status_code=status, raw_error=str(e))
|
| 75 |
|
|
|
|
| 76 |
return e
|
|
|
|
| 38 |
so reactive 429 handling applies to the correct provider. Tests may omit
|
| 39 |
``rate_limiter`` to use the process-wide singleton.
|
| 40 |
"""
|
| 41 |
+
from loguru import logger
|
| 42 |
+
|
| 43 |
message = get_user_facing_error_message(e)
|
| 44 |
+
logger.info(
|
| 45 |
+
"map_error: original_exc_type={} message={}", type(e).__name__, message[:100]
|
| 46 |
+
)
|
| 47 |
limiter = rate_limiter or GlobalRateLimiter.get_instance()
|
| 48 |
|
| 49 |
if isinstance(e, openai.AuthenticationError):
|
| 50 |
+
logger.info("map_error: mapped to AuthenticationError")
|
| 51 |
return AuthenticationError(message, raw_error=str(e))
|
| 52 |
if isinstance(e, openai.RateLimitError):
|
| 53 |
limiter.set_blocked(60)
|
| 54 |
+
logger.info("map_error: mapped to RateLimitError")
|
| 55 |
return RateLimitError(message, raw_error=str(e))
|
| 56 |
if isinstance(e, openai.BadRequestError):
|
| 57 |
+
logger.info("map_error: mapped to InvalidRequestError")
|
| 58 |
return InvalidRequestError(message, raw_error=str(e))
|
| 59 |
if isinstance(e, openai.InternalServerError):
|
| 60 |
raw_message = str(e)
|
| 61 |
if "overloaded" in raw_message.lower() or "capacity" in raw_message.lower():
|
| 62 |
+
logger.info("map_error: mapped to OverloadedError")
|
| 63 |
return OverloadedError(message, raw_error=raw_message)
|
| 64 |
+
logger.info("map_error: mapped to APIError (InternalServerError)")
|
| 65 |
return APIError(message, status_code=500, raw_error=str(e))
|
| 66 |
if isinstance(e, openai.APIError):
|
| 67 |
+
logger.info("map_error: mapped to APIError (openai.APIError)")
|
| 68 |
return APIError(
|
| 69 |
message, status_code=getattr(e, "status_code", 500), raw_error=str(e)
|
| 70 |
)
|
| 71 |
|
| 72 |
if isinstance(e, httpx.HTTPStatusError):
|
| 73 |
status = e.response.status_code
|
| 74 |
+
logger.info("map_error: httpx.HTTPStatusError status={}", status)
|
| 75 |
if status in (401, 403):
|
| 76 |
+
logger.info("map_error: mapped to AuthenticationError (httpx)")
|
| 77 |
return AuthenticationError(message, raw_error=str(e))
|
| 78 |
if status == 429:
|
| 79 |
limiter.set_blocked(60)
|
| 80 |
+
logger.info("map_error: mapped to RateLimitError (httpx)")
|
| 81 |
return RateLimitError(message, raw_error=str(e))
|
| 82 |
if status == 400:
|
| 83 |
+
logger.info("map_error: mapped to InvalidRequestError (httpx)")
|
| 84 |
return InvalidRequestError(message, raw_error=str(e))
|
| 85 |
if status >= 500:
|
| 86 |
if status in (502, 503, 504):
|
| 87 |
+
logger.info("map_error: mapped to OverloadedError (httpx)")
|
| 88 |
return OverloadedError(message, raw_error=str(e))
|
| 89 |
+
logger.info("map_error: mapped to APIError (httpx 5xx)")
|
| 90 |
return APIError(message, status_code=status, raw_error=str(e))
|
| 91 |
+
logger.info("map_error: mapped to APIError (httpx)")
|
| 92 |
return APIError(message, status_code=status, raw_error=str(e))
|
| 93 |
|
| 94 |
+
logger.info("map_error: falling through, returning original exception")
|
| 95 |
return e
|