diff --git a/composer.json b/composer.json index 5e5c47d..23018ee 100644 --- a/composer.json +++ b/composer.json @@ -24,6 +24,7 @@ "require": { "php": "^7.4 | ^8.0", "phrity/net-uri": "^1.0", + "phrity/util-errorhandler": "^1.0", "psr/log": "^1.0 | ^2.0 | ^3.0", "psr/http-message": "^1.0" }, diff --git a/lib/Client.php b/lib/Client.php index a64d140..6270b66 100644 --- a/lib/Client.php +++ b/lib/Client.php @@ -9,8 +9,10 @@ namespace WebSocket; +use ErrorException; use InvalidArgumentException; use Phrity\Net\Uri; +use Phrity\Util\ErrorHandler; use Psr\Http\Message\UriInterface; use Psr\Log\{ LoggerAwareInterface, @@ -330,36 +332,35 @@ protected function connect(): void $persistent = $this->options['persistent'] === true; $flags = STREAM_CLIENT_CONNECT; $flags = $persistent ? $flags | STREAM_CLIENT_PERSISTENT : $flags; - - $error = $errno = $errstr = null; - set_error_handler(function (int $severity, string $message, string $file, int $line) use (&$error) { - $this->logger->warning($message, ['severity' => $severity]); - $error = $message; - }, E_ALL); - - // Open the socket. - $socket = stream_socket_client( - $host_uri, - $errno, - $errstr, - $this->options['timeout'], - $flags, - $context - ); - - restore_error_handler(); - - if (!$socket) { - $error = "Could not open socket to \"{$host_uri->getAuthority()}\": {$errstr} ({$errno}) {$error}."; - $this->logger->error($error); - throw new ConnectionException($error); + $socket = null; + + try { + $handler = new ErrorHandler(); + $socket = $handler->with(function () use ($host_uri, $flags, $context) { + $error = $errno = $errstr = null; + // Open the socket. + return stream_socket_client( + $host_uri, + $errno, + $errstr, + $this->options['timeout'], + $flags, + $context + ); + }); + if (!$socket) { + throw new ErrorException('No socket'); + } + } catch (ErrorException $e) { + $error = "Could not open socket to \"{$host_uri->getAuthority()}\": {$e->getMessage()} ({$e->getCode()})."; + $this->logger->error($error, ['severity' => $e->getSeverity()]); + throw new ConnectionException($error, 0, [], $e); } $this->connection = new Connection($socket, $this->options); $this->connection->setLogger($this->logger); - if (!$this->isConnected()) { - $error = "Invalid stream on \"{$host_uri->getAuthority()}\": {$errstr} ({$errno}) {$error}."; + $error = "Invalid stream on \"{$host_uri->getAuthority()}\"."; $this->logger->error($error); throw new ConnectionException($error); } diff --git a/lib/Server.php b/lib/Server.php index c2c1da1..1521588 100644 --- a/lib/Server.php +++ b/lib/Server.php @@ -10,6 +10,8 @@ namespace WebSocket; use Closure; +use ErrorException; +use Phrity\Util\ErrorHandler; use Psr\Log\{ LoggerAwareInterface, LoggerAwareTrait, @@ -389,22 +391,23 @@ public function getPier(): ?string // Connect when read/write operation is performed. private function connect(): void { - $error = null; - set_error_handler(function (int $severity, string $message, string $file, int $line) use (&$error) { - $this->logger->warning($message, ['severity' => $severity]); - $error = $message; - }, E_ALL); - - if (isset($this->options['timeout'])) { - $socket = stream_socket_accept($this->listening, $this->options['timeout']); - } else { - $socket = stream_socket_accept($this->listening); - } - - restore_error_handler(); - - if (!$socket) { - throw new ConnectionException("Server failed to connect. {$error}"); + try { + $handler = new ErrorHandler(); + $socket = $handler->with(function () { + if (isset($this->options['timeout'])) { + $socket = stream_socket_accept($this->listening, $this->options['timeout']); + } else { + $socket = stream_socket_accept($this->listening); + } + if (!$socket) { + throw new ErrorException('No socket'); + } + return $socket; + }); + } catch (ErrorException $e) { + $error = "Server failed to connect. {$e->getMessage()}"; + $this->logger->error($error, ['severity' => $e->getSeverity()]); + throw new ConnectionException($error, 0, [], $e); } $connection = new Connection($socket, $this->options); diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 818e7cb..60aa5bb 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,14 +1,5 @@ - + lib/ diff --git a/tests/ClientTest.php b/tests/ClientTest.php index c196080..c1a361a 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -9,7 +9,9 @@ namespace WebSocket; +use ErrorException; use Phrity\Net\Uri; +use Phrity\Util\ErrorHandler; use PHPUnit\Framework\TestCase; class ClientTest extends TestCase @@ -516,7 +518,13 @@ public function testUnconnectedClient(): void public function testDeprecated(): void { $client = new Client('ws://localhost:8000/my/mock/path'); - $this->expectDeprecation(); - $this->assertNull($client->getPier()); + (new ErrorHandler())->with(function () use ($client) { + $this->assertNull($client->getPier()); + }, function (ErrorException $e) { + $this->assertEquals( + 'getPier() is deprecated and will be removed in future version. Use getRemoteName() instead.', + $e->getMessage() + ); + }, E_USER_DEPRECATED); } } diff --git a/tests/ServerTest.php b/tests/ServerTest.php index 15c5f79..17e9bab 100644 --- a/tests/ServerTest.php +++ b/tests/ServerTest.php @@ -9,6 +9,8 @@ namespace WebSocket; +use ErrorException; +use Phrity\Util\ErrorHandler; use PHPUnit\Framework\TestCase; class ServerTest extends TestCase @@ -491,4 +493,19 @@ public function testServerDisconnect(): void $this->assertFalse($server->isConnected()); $this->assertTrue(MockSocket::isEmpty()); } + + public function testDeprecated(): void + { + MockSocket::initialize('server.construct', $this); + $server = new Server(); + $this->assertTrue(MockSocket::isEmpty()); + (new ErrorHandler())->with(function () use ($server) { + $this->assertNull($server->getPier()); + }, function (ErrorException $e) { + $this->assertEquals( + 'getPier() is deprecated and will be removed in future version. Use getRemoteName() instead.', + $e->getMessage() + ); + }, E_USER_DEPRECATED); + } }