Skip to content

Commit 0eba38d

Browse files
committed
Improve error messages when accepting connections with errno/errstr
1 parent 4ea75eb commit 0eba38d

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

src/TcpServer.php

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,28 @@ public function resume()
213213
$this->loop->addReadStream($this->master, function ($master) use ($that) {
214214
$newSocket = @\stream_socket_accept($master, 0);
215215
if (false === $newSocket) {
216-
$that->emit('error', array(new \RuntimeException('Error accepting new connection')));
216+
// Match errstr from PHP's warning message.
217+
// stream_socket_accept(): accept failed: Connection timed out
218+
$error = \error_get_last();
219+
$errstr = \preg_replace('#.*: #', '', $error['message']);
220+
221+
// Go through list of possible error constants to find matching errno.
222+
// @codeCoverageIgnoreStart
223+
$errno = 0;
224+
if (\function_exists('socket_strerror')) {
225+
foreach (\get_defined_constants(false) as $name => $value) {
226+
if (\strpos($name, 'SOCKET_E') === 0 && \socket_strerror($value) === $errstr) {
227+
$errno = $value;
228+
break;
229+
}
230+
}
231+
}
232+
// @codeCoverageIgnoreEnd
233+
234+
$that->emit('error', array(new \RuntimeException(
235+
'Unable to accept new connection: ' . $errstr,
236+
$errno
237+
)));
217238

218239
return;
219240
}

tests/TcpServerTest.php

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,10 @@ public function testEmitsErrorWhenAcceptListenerFails()
287287

288288
$server = new TcpServer(0, $loop);
289289

290-
$server->on('error', $this->expectCallableOnceWith($this->isInstanceOf('RuntimeException')));
290+
$exception = null;
291+
$server->on('error', function ($e) use (&$exception) {
292+
$exception = $e;
293+
});
291294

292295
$this->assertNotNull($listener);
293296
$socket = stream_socket_server('tcp://127.0.0.1:0');
@@ -297,6 +300,23 @@ public function testEmitsErrorWhenAcceptListenerFails()
297300
$time = microtime(true) - $time;
298301

299302
$this->assertLessThan(1, $time);
303+
304+
$this->assertInstanceOf('RuntimeException', $exception);
305+
assert($exception instanceof \RuntimeException);
306+
$this->assertStringStartsWith('Unable to accept new connection: ', $exception->getMessage());
307+
308+
return $exception;
309+
}
310+
311+
/**
312+
* @param \RuntimeException $e
313+
* @requires extension sockets
314+
* @depends testEmitsErrorWhenAcceptListenerFails
315+
*/
316+
public function testEmitsTimeoutErrorWhenAcceptListenerFails(\RuntimeException $exception)
317+
{
318+
$this->assertEquals('Unable to accept new connection: ' . socket_strerror(SOCKET_ETIMEDOUT), $exception->getMessage());
319+
$this->assertEquals(SOCKET_ETIMEDOUT, $exception->getCode());
300320
}
301321

302322
public function testListenOnBusyPortThrows()

0 commit comments

Comments
 (0)