8000 bug #37927 [HttpClient] fix chaining promises returned by HttplugClie… · symfony/symfony@fc3095f · GitHub
[go: up one dir, main page]

Skip to content

Commit fc3095f

Browse files
committed
bug #37927 [HttpClient] fix chaining promises returned by HttplugClient (CthulhuDen)
This PR was merged into the 5.1 branch. Discussion ---------- [HttpClient] fix chaining promises returned by HttplugClient | Q | A | ------------- | --- | Branch? | 5.1 | Bug fix? | yes | New feature? | no | Deprecations? | no | Tickets | Fix #37925 | License | MIT Guzzle runtime does not play too well with foreign promises, which can be fixed by wrapping them with `promise_for`. Added failing test case from #37925 and suggested fix. Should not break BC because `then` callback results get resolved before being passed to next `then` callback or returned from `wait`. Commits ------- 75043a1 [HttpClient] fix chaining promises returned by HttplugClient
2 parents 885390f + 75043a1 commit fc3095f

File tree

2 files changed

+52
-1
lines changed

2 files changed

+52
-1
lines changed

src/Symfony/Component/HttpClient/Response/HttplugPromise.php

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\HttpClient\Response;
1313

14+
use function GuzzleHttp\Promise\promise_for;
1415
use GuzzleHttp\Promise\PromiseInterface as GuzzlePromiseInterface;
1516
use Http\Promise\Promise as HttplugPromiseInterface;
1617
use Psr\Http\Message\ResponseInterface as Psr7ResponseInterface;
@@ -31,7 +32,10 @@ public function __construct(GuzzlePromiseInterface $promise)
3132

3233
public function then(callable $onFulfilled = null, callable $onRejected = null): self
3334
{
34-
return new self($this->promise->then($onFulfilled, $onRejected));
35+
return new self($this->promise->then(
36+
$this->wrapThenCallback($onFulfilled),
37+
$this->wrapThenCallback($onRejected)
38+
));
3539
}
3640

3741
public function cancel(): void
@@ -62,4 +66,15 @@ public function wait($unwrap = true)
6266

6367
return $result;
6468
}
69+
70+
private function wrapThenCallback(?callable $callback): ?callable
71+
{
72+
if (null === $callback) {
73+
return null;
74+
}
75+
76+
return static function ($value) use ($callback) {
77+
return promise_for($callback($value));
78+
};
79+
}
6580
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\HttpClient\Tests\Response;
13+
14+
use GuzzleHttp\Promise\Promise;
15+
use PHPUnit\Framework\TestCase;
16+
use Symfony\Component\HttpClient\Response\HttplugPromise;
17+
18+
class HttplugPromiseTest extends TestCase
19+
{
20+
publ A6CB ic function testComplexNesting()
21+
{
22+
$mkPromise = function ($result): HttplugPromise {
23+
$guzzlePromise = new Promise(function () use (&$guzzlePromise, $result) {
24+
$guzzlePromise->resolve($result);
25+
});
26+
27+
return new HttplugPromise($guzzlePromise);
28+
};
29+
30+
$promise1 = $mkPromise('result');
31+
$promise2 = $promise1->then($mkPromise);
32+
$promise3 = $promise2->then(function ($result) { return $result; });
33+
34+
$this->assertSame('result', $promise3->wait());
35+
}
36+
}

0 commit comments

Comments
 (0)
0