Carry the HTTP status code in the exceptions ApiCall::getException() creates - #125
Merged
tharropoulos merged 1 commit intoSep 10, 2026
Merged
Conversation
…creates Every exception built by ApiCall::getException() was constructed without a code, so $exception->getCode() is always 0. A caller that wants the status (to log it, to decide between retry and give-up, or to map it to its own error) has to reverse-map the exception class, and the classes cannot express the difference between, say, a 429 and a 502: both arrive as a bare TypesenseClientError. Pass the status code as the exception code. The message is still empty at construction time and is still set by ApiCall::setMessage() afterwards, so messages, exception classes and the retry behaviour are unchanged; the only difference is that getCode() now returns the HTTP status where it returned 0 before (HTTPStatus0Error keeps 0). Two tests: one for every mapped and unmapped status, and one end to end through ApiCall::get() with a mocked 404 response that checks both the code and the server message.
tharropoulos
approved these changes
Sep 10, 2026
Collaborator
|
Thanks for the contribution! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Every exception created by
ApiCall::getException()is constructed without a code, so$exception->getCode()is always0:A caller that wants the status has to reverse-map the exception class, and the classes cannot express the difference between statuses that share a class: 403, 429, 502 and 504 all arrive as a bare
TypesenseClientError. In our application we needed the status to decide between "retry later" (0, 408, 429, 5xx) and "give up" (other 4xx) and to log it; we have been running this change from a fork since July.Change
getException()passes the HTTP status as the exception code. The message is still empty at construction and is still set by->setMessage()inmakeRequest(), so:getCode()returns the HTTP status where it returned0before (HTTPStatus0Errorkeeps0).This is the convention of the other HTTP-facing PHP clients (Guzzle's
RequestException, Symfony'sHttpExceptionInterface::getStatusCode()), and it is additive for callers: code that never readgetCode()sees no difference.Tests
testExceptionsCarryTheHttpStatusCode: every mapped status (0, 400, 401, 404, 409, 422, 500, 503) and unmapped ones (403, 408, 429, 502, 504) return an exception whose code is the status and whose message is empty.testThrownExceptionsCarryTheStatusCodeAndTheServerMessage: end to end throughApiCall::get()with a mocked 404 response:ObjectNotFound, code 404, message from the server body.vendor/bin/phpunit tests/Feature/ApiCallRetryTest.php: 15 tests, 58 assertions, OK. Full suite against Typesense 30.2: the same 6 cases fail with and without this change (analytics events and curation sets, environment-specific), everything else passes.phpcsreports no new violations in the two touched files (the pre-existing ones inApiCall.phpare untouched).🤖 Generated with Claude Code