You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Connection._make_request (actionkit/connection.py:135-148) only special-cases retry_codes (just 500). For any other HTTPError, if the response has a non-empty body, it is unconditionally converted to ValidationError — regardless of status code:
Only an empty-bodied error response surfaces as a raw requests.HTTPError.
Why this matters
Real ActionKit error responses almost always carry a JSON body. That means every call site in this library written as except HTTPError as e: if e.response.status_code == 400/404/409: ... never actually sees that exception in production, because ValidationError doesn't subclass HTTPError and has no .response/.status_code. The status-code-specific handling silently doesn't run; ValidationError propagates instead.
Confirmed call sites whose special-casing is likely dead code as a result:
This was verified empirically with tests (see the new tests/test_connection.py::test_error_with_body_raises_validation_error_regardless_of_status and the companion tests in tests/test_httpmethods.py, tests/test_donationaction.py, tests/test_transactions.py that pin the current, likely-unintended behavior at each call site).
Suggested fix direction (not decided)
Either:
Make _make_request raise ValidationError as a subclass of (or alongside preserving) HTTPError/its .response, so existing except HTTPError status-code checks keep working, or
Audit and update each of the call sites above to catch ValidationError instead of/in addition to HTTPError.
Worth a dedicated design discussion rather than a quick patch, since it touches several call sites' error-handling contracts at once.
What's happening
Connection._make_request(actionkit/connection.py:135-148) only special-casesretry_codes(just500). For any otherHTTPError, if the response has a non-empty body, it is unconditionally converted toValidationError— regardless of status code:Only an empty-bodied error response surfaces as a raw
requests.HTTPError.Why this matters
Real ActionKit error responses almost always carry a JSON body. That means every call site in this library written as
except HTTPError as e: if e.response.status_code == 400/404/409: ...never actually sees that exception in production, becauseValidationErrordoesn't subclassHTTPErrorand has no.response/.status_code. The status-code-specific handling silently doesn't run;ValidationErrorpropagates instead.Confirmed call sites whose special-casing is likely dead code as a result:
actionkit/httpmethods.py—delete()'signore_404=True404-swallowing (httpmethods.py:49-54)actionkit/donationaction.py—push()'s 409-duplicate and 400 handling (donationaction.py:105-115),set_push_status()'s 400 handling,delete_donationaction()'s 400/404 handlingactionkit/transactions.py—reverse()'s 400/404 handling (see also Transactions.reverse()'s "already reversed" ValidationError check can never match #18, a second, independent bug in theValidationErrorbranch that was meant to be the real handler for this)This was verified empirically with tests (see the new
tests/test_connection.py::test_error_with_body_raises_validation_error_regardless_of_statusand the companion tests intests/test_httpmethods.py,tests/test_donationaction.py,tests/test_transactions.pythat pin the current, likely-unintended behavior at each call site).Suggested fix direction (not decided)
Either:
_make_requestraiseValidationErroras a subclass of (or alongside preserving)HTTPError/its.response, so existingexcept HTTPErrorstatus-code checks keep working, orValidationErrorinstead of/in addition toHTTPError.Worth a dedicated design discussion rather than a quick patch, since it touches several call sites' error-handling contracts at once.