fix: preserve HTTP status for API errors - #238
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #238 +/- ##
===========================================
+ Coverage 82.66% 96.42% +13.75%
===========================================
Files 4 65 +61
Lines 75 3525 +3450
===========================================
+ Hits 62 3399 +3337
- Misses 13 126 +113 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
When the response body is not usable JSON (CDN HTML, empty 5xx, proxies), use the real HTTP status for 4xx/5xx instead of always raising a fake 500. Mirror sync and async request paths.
8451c2d to
98943ad
Compare
|
Updated this PR after rebasing it onto the current main branch. The original version preserved the HTTP status for non-JSON responses. The request layer had the same false-success bug for valid JSON error responses that omitted Example before this update:
After this update, the same response raises New regression proof:
Successful responses and JSON errors that already include |
What
Preserve the real HTTP status code when the Resend API returns an error.
This now works for both kinds of error responses:
statusCodefieldThe change applies to both sync and async requests.
The bug
The HTTP clients already returned the response body, HTTP status, and headers. The request layer kept the body and headers but discarded the HTTP status.
It then decided whether a request failed by looking only for
statusCodeinside the JSON body. If the API returned HTTP 429 with this valid JSON:{ "name": "rate_limit_exceeded", "message": "Too many requests" }the SDK found no JSON
statusCodeand returned the error object as normal successful data.Non-JSON error responses had a related problem: their real 401, 429, 502, or 503 status was replaced with 500.
Fix
Each request now stores the HTTP status together with the response headers.
When deciding whether to raise an exception:
statusCoderemains supported for backward compatibilityThis keeps the existing typed exception mapping. For example, HTTP 429 with
name: rate_limit_exceedednow raisesRateLimitErrorwithcode == 429.Test proof
New regression tests cover the exact false-success path:
statusCoderaisesRateLimitErrorstatusCoderaisesValidationErrorThe PR also keeps its existing defensive coverage:
Local validation after rebasing onto current
main:tox -e lint: passedtox -e mypy: passed, 167 source filestox -e py -- tests/request_test.py: 9 passedtox -e py: 500 passedCompatibility
Successful responses are unchanged. JSON error bodies that already include
statusCodecontinue to work as before.