[HttpClient] Fix promise behavior in HttplugClient #37491
Merged
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.
The Problem
Promises have 2 important methods:
thenandwait.To implement Httplug's promise interface, we built
HttplugPromiseon top of Guzzle promise.However, when an error occurred (Httplug
NetworkExceptionthrown) while init the request/before actually sending the request,HttplugClient::sendAsyncRequestwill return aHttp\Promise\RejectedPromise, which is a dummy implementation.If the
thencallable returns a promise-like object,Http\Promise\RejectedPromisewill treat it as plain value.Guzzle promise will try to resolve the promise-like value, which is an object that has
thenmethod on it.https://github.com/guzzle/promises/blob/bbf3b200bc83c1e9298580a9f99b9be248543467/src/Promise.php#L116
To fix this, I edited
src/Symfony/Component/HttpClient/HttplugClient.php.Next, let me explain why to edit
src/Symfony/Component/HttpClient/Response/HttplugPromise.php.After the previous fix, when a Guzzle promise returned by the
thencallable, things will work.However, If I return a
HttplugPromiseInterface, it doesn't work, because Guzzle promisewaitthe return value (result)only if it's a Guzzle promise.
https://github.com/guzzle/promises/blob/bbf3b200bc83c1e9298580a9f99b9be248543467/src/Promise.php#L63
To fix this, I referenced the
waitcode of Guzzle promise and edited ourHttplugPromise.How this fix make sense
So, why to return a promise from the
thencallable?This let us change the promise chain according to current promise's result (fulfilled/rejected).
For example, we can retry an HTTP request if it failed.
Please take a look at my test code.