Skip to content

Commit 1b373da

Browse files
committed
Improve error message to show last error family first
1 parent 6db981c commit 1b373da

File tree

2 files changed

+18
-9
lines changed

2 files changed

+18
-9
lines changed

src/HappyEyeBallsConnectionBuilder.php

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ final class HappyEyeBallsConnectionBuilder
4949
public $resolve;
5050
public $reject;
5151

52+
public $lastErrorFamily;
5253
public $lastError6;
5354
public $lastError4;
5455

@@ -128,8 +129,10 @@ public function resolve($type, $reject)
128129

129130
if ($type === Message::TYPE_A) {
130131
$that->lastError4 = $e->getMessage();
132+
$that->lastErrorFamily = 4;
131133
} else {
132134
$that->lastError6 = $e->getMessage();
135+
$that->lastErrorFamily = 6;
133136
}
134137

135138
// cancel next attempt timer when there are no more IPs to connect to anymore
@@ -139,7 +142,7 @@ public function resolve($type, $reject)
139142
}
140143

141144
if ($that->hasBeenResolved() && $that->ipsCount === 0) {
142-
$reject($that->error());
145+
$reject(new \RuntimeException($that->error()));
143146
}
144147

145148
throw $e;
@@ -172,8 +175,10 @@ public function check($resolve, $reject)
172175

173176
if (\strpos($ip, ':') === false) {
174177
$that->lastError4 = $e->getMessage();
178+
$that->lastErrorFamily = 4;
175179
} else {
176180
$that->lastError6 = $e->getMessage();
181+
$that->lastErrorFamily = 6;
177182
}
178183

179184
// start next connection attempt immediately on error
@@ -193,7 +198,7 @@ public function check($resolve, $reject)
193198
if ($that->ipsCount === $that->failureCount) {
194199
$that->cleanUp();
195200

196-
$reject($that->error());
201+
$reject(new \RuntimeException($that->error()));
197202
}
198203
});
199204

@@ -326,14 +331,16 @@ public function mixIpsIntoConnectQueue(array $ips)
326331

327332
/**
328333
* @internal
329-
* @return \RuntimeException
334+
* @return string
330335
*/
331336
public function error()
332337
{
333338
if ($this->lastError4 === $this->lastError6) {
334339
$message = $this->lastError6;
340+
} elseif ($this->lastErrorFamily === 6) {
341+
$message = 'Last error for IPv6: ' . $this->lastError6 . '. Previous error for IPv4: ' . $this->lastError4;
335342
} else {
336-
$message = 'Last error for IPv6: ' . $this->lastError6 . '. Last error for IPv4: ' . $this->lastError4;
343+
$message = 'Last error for IPv4: ' . $this->lastError4 . '. Previous error for IPv6: ' . $this->lastError6;
337344
}
338345

339346
if ($this->hasBeenResolved() && $this->ipsCount === 0) {
@@ -346,6 +353,6 @@ public function error()
346353
$message = ': ' . $message;
347354
}
348355

349-
return new \RuntimeException('Connection to ' . $this->uri . ' failed' . $message);
356+
return 'Connection to ' . $this->uri . ' failed' . $message;
350357
}
351358
}

tests/HappyEyeBallsConnectionBuilderTest.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,13 @@ public function testConnectWillRejectWhenBothDnsLookupsRejectWithDifferentMessag
7373
$connector = $this->getMockBuilder('React\Socket\ConnectorInterface')->getMock();
7474
$connector->expects($this->never())->method('connect');
7575

76+
$deferred = new Deferred();
7677
$resolver = $this->getMockBuilder('React\Dns\Resolver\ResolverInterface')->getMock();
7778
$resolver->expects($this->exactly(2))->method('resolveAll')->withConsecutive(
7879
array('reactphp.org', Message::TYPE_AAAA),
7980
array('reactphp.org', Message::TYPE_A)
8081
)->willReturnOnConsecutiveCalls(
81-
\React\Promise\reject(new \RuntimeException('DNS6 error')),
82+
$deferred->promise(),
8283
\React\Promise\reject(new \RuntimeException('DNS4 error'))
8384
);
8485

@@ -89,14 +90,15 @@ public function testConnectWillRejectWhenBothDnsLookupsRejectWithDifferentMessag
8990
$builder = new HappyEyeBallsConnectionBuilder($loop, $connector, $resolver, $uri, $host, $parts);
9091

9192
$promise = $builder->connect();
93+
$deferred->reject(new \RuntimeException('DNS6 error'));
9294

9395
$exception = null;
9496
$promise->then(null, function ($e) use (&$exception) {
9597
$exception = $e;
9698
});
9799

98100
$this->assertInstanceOf('RuntimeException', $exception);
99-
$this->assertEquals('Connection to tcp://reactphp.org:80 failed during DNS lookup. Last error for IPv6: DNS6 error. Last error for IPv4: DNS4 error', $exception->getMessage());
101+
$this->assertEquals('Connection to tcp://reactphp.org:80 failed during DNS lookup. Last error for IPv6: DNS6 error. Previous error for IPv4: DNS4 error', $exception->getMessage());
100102
}
101103

102104
public function testConnectWillStartDelayTimerWhenIpv4ResolvesAndIpv6IsPending()
@@ -433,7 +435,7 @@ public function testConnectWillRejectWhenOnlyTcp6ConnectionRejectsAndCancelNextA
433435
});
434436

435437
$this->assertInstanceOf('RuntimeException', $exception);
436-
$this->assertEquals('Connection to tcp://reactphp.org:80 failed: Last error for IPv6: Connection refused. Last error for IPv4: DNS failed', $exception->getMessage());
438+
$this->assertEquals('Connection to tcp://reactphp.org:80 failed: Last error for IPv6: Connection refused. Previous error for IPv4: DNS failed', $exception->getMessage());
437439
}
438440

439441
public function testConnectWillRejectWhenOnlyTcp4ConnectionRejectsAndWillNeverStartNextAttemptTimer()
@@ -469,7 +471,7 @@ public function testConnectWillRejectWhenOnlyTcp4ConnectionRejectsAndWillNeverSt
469471
});
470472

471473
$this->assertInstanceOf('RuntimeException', $exception);
472-
$this->assertEquals('Connection to tcp://reactphp.org:80 failed: Last error for IPv6: DNS failed. Last error for IPv4: Connection refused', $exception->getMessage());
474+
$this->assertEquals('Connection to tcp://reactphp.org:80 failed: Last error for IPv4: Connection refused. Previous error for IPv6: DNS failed', $exception->getMessage());
473475
}
474476

475477
public function testConnectWillRejectWhenAllConnectionsRejectAndCancelNextAttemptTimerImmediately()

0 commit comments

Comments
 (0)