Spaces:
Running
Running
Better handle rate limit errors that come as 413 or BadRequestError.
Browse filesAlso detect rate limits from response body type.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- providers/error_mapping.py +22 -0
providers/error_mapping.py
CHANGED
|
@@ -54,6 +54,12 @@ def map_error(
|
|
| 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):
|
|
@@ -79,9 +85,25 @@ def map_error(
|
|
| 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)")
|
|
|
|
| 54 |
logger.info("map_error: mapped to RateLimitError")
|
| 55 |
return RateLimitError(message, raw_error=str(e))
|
| 56 |
if isinstance(e, openai.BadRequestError):
|
| 57 |
+
# Check if it's actually a rate limit in disguise
|
| 58 |
+
raw = str(e).lower()
|
| 59 |
+
if "too_many_requests" in raw or "rate_limit" in raw or "quota" in raw:
|
| 60 |
+
limiter.set_blocked(60)
|
| 61 |
+
logger.info("map_error: BadRequestError actually rate limit")
|
| 62 |
+
return RateLimitError(message, raw_error=str(e))
|
| 63 |
logger.info("map_error: mapped to InvalidRequestError")
|
| 64 |
return InvalidRequestError(message, raw_error=str(e))
|
| 65 |
if isinstance(e, openai.InternalServerError):
|
|
|
|
| 85 |
limiter.set_blocked(60)
|
| 86 |
logger.info("map_error: mapped to RateLimitError (httpx)")
|
| 87 |
return RateLimitError(message, raw_error=str(e))
|
| 88 |
+
if status == 413:
|
| 89 |
+
# "Request too large" - often actually a rate limit or quota issue
|
| 90 |
+
limiter.set_blocked(60)
|
| 91 |
+
logger.info("map_error: mapped to RateLimitError (413)")
|
| 92 |
+
return RateLimitError(message, raw_error=str(e))
|
| 93 |
if status == 400:
|
| 94 |
logger.info("map_error: mapped to InvalidRequestError (httpx)")
|
| 95 |
return InvalidRequestError(message, raw_error=str(e))
|
| 96 |
+
# Check response body for rate limit indicators
|
| 97 |
+
try:
|
| 98 |
+
body = e.response.json()
|
| 99 |
+
if body and isinstance(body, dict):
|
| 100 |
+
err_type = body.get("type", "")
|
| 101 |
+
if "too_many_requests" in err_type or "rate_limit" in err_type.lower():
|
| 102 |
+
limiter.set_blocked(60)
|
| 103 |
+
logger.info("map_error: detected rate limit from response body")
|
| 104 |
+
return RateLimitError(message, raw_error=str(e))
|
| 105 |
+
except Exception:
|
| 106 |
+
pass
|
| 107 |
if status >= 500:
|
| 108 |
if status in (502, 503, 504):
|
| 109 |
logger.info("map_error: mapped to OverloadedError (httpx)")
|