Skip to content

Commit

Permalink
Merge pull request #258 from clue-labs/unhandled-rejection
Browse files Browse the repository at this point in the history
Internal improvement to avoid unhandled rejection for future Promise API
  • Loading branch information
WyriHaximus authored Jun 25, 2021
2 parents eef95f0 + d2040a9 commit 43c9f20
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 5 deletions.
12 changes: 7 additions & 5 deletions src/HappyEyeBallsConnectionBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ public function connect()

$that->resolverPromises[Message::TYPE_AAAA] = $that->resolve(Message::TYPE_AAAA, $reject)->then($lookupResolve(Message::TYPE_AAAA));
$that->resolverPromises[Message::TYPE_A] = $that->resolve(Message::TYPE_A, $reject)->then(function (array $ips) use ($that, &$timer) {
// happy path: IPv6 has resolved already, continue with IPv4 addresses
if ($that->resolved[Message::TYPE_AAAA] === true) {
// happy path: IPv6 has resolved already (or could not resolve), continue with IPv4 addresses
if ($that->resolved[Message::TYPE_AAAA] === true || !$ips) {
return $ips;
}

Expand Down Expand Up @@ -117,8 +117,9 @@ public function connect()
* @internal
* @param int $type DNS query type
* @param callable $reject
* @return \React\Promise\PromiseInterface<string[],\Exception> Returns a promise
* that resolves list of IP addresses on success or rejects with an \Exception on error.
* @return \React\Promise\PromiseInterface<string[]> Returns a promise that
* always resolves with a list of IP addresses on success or an empty
* list on error.
*/
public function resolve($type, $reject)
{
Expand All @@ -145,7 +146,8 @@ public function resolve($type, $reject)
$reject(new \RuntimeException($that->error()));
}

throw $e;
// Exception already handled above, so don't throw an unhandled rejection here
return array();
});
}

Expand Down
21 changes: 21 additions & 0 deletions tests/HappyEyeBallsConnectionBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -677,6 +677,27 @@ public function testCancelConnectWillRejectPromiseAndCancelPendingIpv6Connection
$this->assertEquals('Connection to tcp://reactphp.org:80 cancelled', $exception->getMessage());
}

public function testResolveWillReturnResolvedPromiseWithEmptyListWhenDnsResolverFails()
{
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();

$connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();

$resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock();
$resolver->expects($this->once())->method('resolveAll')->with('reactphp.org', Message::TYPE_A)->willReturn(\React\Promise\reject(new \RuntimeException()));

$uri = 'tcp://reactphp.org:80';
$host = 'reactphp.org';
$parts = parse_url($uri);

$builder = new HappyEyeBallsConnectionBuilder($loop, $connector, $resolver, $uri, $host, $parts);

$promise = $builder->resolve(Message::TYPE_A, $this->expectCallableNever());

$this->assertInstanceof('React\Promise\PromiseInterface', $promise);
$promise->then($this->expectCallableOnceWith(array()), $this->expectCallableNever());
}

public function testAttemptConnectionWillConnectViaConnectorToGivenIpWithPortAndHostnameFromUriParts()
{
$loop = $this->getMockBuilder('React\EventLoop\LoopInterface')->getMock();
Expand Down

0 comments on commit 43c9f20

Please sign in to comment.