[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:
then
andwait
.To implement Httplug's promise interface, we built
HttplugPromise
on top of Guzzle promise.However, when an error occurred (Httplug
NetworkException
thrown) while init the request/before actually sending the request,HttplugClient::sendAsyncRequest
will return aHttp\Promise\RejectedPromise
, which is a dummy implementation.If the
then
callable returns a promise-like object,Http\Promise\RejectedPromise
will treat it as plain value.Guzzle promise will try to resolve the promise-like value, which is an object that has
then
method 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
then
callable, things will work.However, If I return a
HttplugPromiseInterface
, it doesn't work, because Guzzle promisewait
the 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
wait
code of Guzzle promise and edited ourHttplugPromise
.How this fix make sense
So, why to return a promise from the
then
callable?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.