Skip to content

Commit b59f8f1

Browse files
authored
Merge pull request #168 from clue-labs/unix-errors
Improve Unix domain socket (UDS) server error messages
2 parents 476e264 + 9f1d258 commit b59f8f1

File tree

4 files changed

+50
-1
lines changed

4 files changed

+50
-1
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,14 @@ $first = new UnixServer('/tmp/same.sock', $loop);
706706
$second = new UnixServer('/tmp/same.sock', $loop);
707707
```
708708

709+
> Note that these error conditions may vary depending on your system and/or
710+
configuration.
711+
In particular, Zend PHP does only report "Unknown error" when the UDS path
712+
already exists and can not be bound. You may want to check `is_file()` on the
713+
given UDS path to report a more user-friendly error message in this case.
714+
See the exception message and code for more details about the actual error
715+
condition.
716+
709717
Whenever a client connects, it will emit a `connection` event with a connection
710718
instance implementing [`ConnectionInterface`](#connectioninterface):
711719

src/UnixServer.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,18 @@ public function __construct($path, LoopInterface $loop, array $context = array()
6161
stream_context_create(array('socket' => $context))
6262
);
6363
if (false === $this->master) {
64-
throw new RuntimeException('Failed to listen on unix domain socket "' . $path . '": ' . $errstr, $errno);
64+
// PHP does not seem to report errno/errstr for Unix domain sockets (UDS) right now.
65+
// This only applies to UDS server sockets, see also https://3v4l.org/NAhpr.
66+
// Parse PHP warning message containing unknown error, HHVM reports proper info at least.
67+
if ($errno === 0 && $errstr === '') {
68+
$error = error_get_last();
69+
if (preg_match('/\(([^\)]+)\)|\[(\d+)\]: (.*)/', $error['message'], $match)) {
70+
$errstr = isset($match[3]) ? $match['3'] : $match[1];
71+
$errno = isset($match[2]) ? (int)$match[2] : 0;
72+
}
73+
}
74+
75+
throw new RuntimeException('Failed to listen on Unix domain socket "' . $path . '": ' . $errstr, $errno);
6576
}
6677
stream_set_blocking($this->master, 0);
6778

tests/ServerTest.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ public function testConstructorCreatesExpectedTcpServer()
5050

5151
public function testConstructorCreatesExpectedUnixServer()
5252
{
53+
if (!in_array('unix', stream_get_transports())) {
54+
$this->markTestSkipped('Unix domain sockets (UDS) not supported on your platform (Windows?)');
55+
}
56+
5357
$loop = Factory::create();
5458

5559
$server = new Server($this->getRandomSocketUri(), $loop);
@@ -64,6 +68,28 @@ public function testConstructorCreatesExpectedUnixServer()
6468
$server->close();
6569
}
6670

71+
public function testConstructorThrowsForExistingUnixPath()
72+
{
73+
if (!in_array('unix', stream_get_transports())) {
74+
$this->markTestSkipped('Unix domain sockets (UDS) not supported on your platform (Windows?)');
75+
}
76+
77+
$loop = Factory::create();
78+
79+
try {
80+
$server = new Server('unix://' . __FILE__, $loop);
81+
$this->fail();
82+
} catch (\RuntimeException $e) {
83+
if ($e->getCode() === 0) {
84+
// Zend PHP does not currently report a sane error
85+
$this->assertStringEndsWith('Unknown error', $e->getMessage());
86+
} else {
87+
$this->assertEquals(SOCKET_EADDRINUSE, $e->getCode());
88+
$this->assertStringEndsWith('Address already in use', $e->getMessage());
89+
}
90+
}
91+
}
92+
6793
public function testEmitsConnectionForNewConnection()
6894
{
6995
$loop = Factory::create();

tests/UnixServerTest.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ class UnixServerTest extends TestCase
1919
*/
2020
public function setUp()
2121
{
22+
if (!in_array('unix', stream_get_transports())) {
23+
$this->markTestSkipped('Unix domain sockets (UDS) not supported on your platform (Windows?)');
24+
}
25+
2226
$this->loop = Factory::create();
2327
$this->uds = $this->getRandomSocketUri();
2428
$this->server = new UnixServer($this->uds, $this->loop);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy