From 423c047b7ff28050d623c905a0d0bd83d318d984 Mon Sep 17 00:00:00 2001 From: James Titcumb Date: Mon, 16 Dec 2019 15:53:02 +0000 Subject: [PATCH 1/3] Added private method to capture errors and convert to exceptions --- src/Connector/SocketConnector.php | 35 +++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/src/Connector/SocketConnector.php b/src/Connector/SocketConnector.php index ec61457c..09270eca 100644 --- a/src/Connector/SocketConnector.php +++ b/src/Connector/SocketConnector.php @@ -54,6 +54,27 @@ public function __construct(string $socketPath) } } + /** @return mixed */ + private function convertErrorsToExceptions(callable $functionToRun) + { + // phpcs:disable SlevomatCodingStandard.TypeHints.TypeHintDeclaration.IncorrectReturnTypeHint + set_error_handler( + static function (int $severity, string $message, string $file = '', int $line = 0, array $context = []) : bool { + throw new ErrorException($message, 0, $severity, $file, $line); + }, + E_STRICT | E_NOTICE | E_WARNING + ); + // phpcs:enable + + try { + $returnValue = $functionToRun(); + } finally { + restore_error_handler(); + } + + return $returnValue; + } + public function connect() : void { if ($this->connected()) { @@ -63,22 +84,14 @@ public function connect() : void try { socket_clear_error($this->socket); - // phpcs:disable SlevomatCodingStandard.TypeHints.TypeHintDeclaration.IncorrectReturnTypeHint - set_error_handler( - static function (int $severity, string $message, string $file = '', int $line = 0, array $context = []) : bool { - throw new ErrorException($message, 0, $severity, $file, $line); - }, - E_STRICT | E_NOTICE | E_WARNING - ); - // phpcs:enable + $this->connected = $this->convertErrorsToExceptions(function () { + return socket_connect($this->socket, $this->socketPath); + }); - $this->connected = socket_connect($this->socket, $this->socketPath); register_shutdown_function([&$this, 'shutdown']); } catch (Throwable $e) { $this->connected = false; throw FailedToConnect::fromSocketPathAndPrevious($this->socketPath, $e); - } finally { - restore_error_handler(); } } From 1b6aa8a8fb20cee8e58c481146f36ae68e1b2c5b Mon Sep 17 00:00:00 2001 From: James Titcumb Date: Tue, 17 Dec 2019 11:33:25 +0000 Subject: [PATCH 2/3] Ensure exception is raised with non existent socket --- tests/Unit/Connector/SocketConnectorTest.php | 22 ++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 tests/Unit/Connector/SocketConnectorTest.php diff --git a/tests/Unit/Connector/SocketConnectorTest.php b/tests/Unit/Connector/SocketConnectorTest.php new file mode 100644 index 00000000..f2f3255b --- /dev/null +++ b/tests/Unit/Connector/SocketConnectorTest.php @@ -0,0 +1,22 @@ +expectException(FailedToConnect::class); + $this->expectExceptionMessage('socket_connect(): unable to connect [2]: No such file or directory'); + $connector->connect(); + } +} From 3df61bfb8d84fecdd21e63a4928ec8e218786dad Mon Sep 17 00:00:00 2001 From: James Titcumb Date: Tue, 17 Dec 2019 11:49:32 +0000 Subject: [PATCH 3/3] Suppress errors being emitted from socket functions since we already correctly handle these and read socket_last_error() --- src/Connector/SocketConnector.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Connector/SocketConnector.php b/src/Connector/SocketConnector.php index 09270eca..dc129035 100644 --- a/src/Connector/SocketConnector.php +++ b/src/Connector/SocketConnector.php @@ -113,22 +113,22 @@ public function sendCommand(Command $message) : string // Socket error is a global state, so we must reset to a known state first... socket_clear_error($this->socket); - if (socket_send($this->socket, pack('N', $size), 4, 0) === false) { + if (@socket_send($this->socket, pack('N', $size), 4, 0) === false) { throw Exception\FailedToSendCommand::writingMessageSizeToSocket($message, $this->socket, $this->socketPath); } - if (socket_send($this->socket, $serializedJsonString, $size, 0) === false) { + if (@socket_send($this->socket, $serializedJsonString, $size, 0) === false) { throw Exception\FailedToSendCommand::writingMessageContentToSocket($message, $this->socket, $this->socketPath); } // Read the response back and drop it. Needed for socket liveness - $responseLength = socket_read($this->socket, 4); + $responseLength = @socket_read($this->socket, 4); if ($responseLength === false) { throw Exception\FailedToSendCommand::readingResponseSizeFromSocket($message, $this->socket, $this->socketPath); } - $dataRead = socket_read($this->socket, unpack('N', $responseLength)[1]); + $dataRead = @socket_read($this->socket, unpack('N', $responseLength)[1]); if ($dataRead === false) { throw Exception\FailedToSendCommand::readingResponseContentFromSocket($message, $this->socket, $this->socketPath);