Skip to content

Commit

Permalink
Merge pull request #144 from scoutapp/wrap-socket-calls-with-error-ha…
Browse files Browse the repository at this point in the history
…ndler

Wrap socket calls with error handler
  • Loading branch information
Chris Schneider authored Dec 17, 2019
2 parents 333db35 + 3df61bf commit 6226474
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 15 deletions.
43 changes: 28 additions & 15 deletions src/Connector/SocketConnector.php
Original file line number Diff line number Diff line change
Expand Up @@ -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()) {
Expand All @@ -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();
}
}

Expand All @@ -100,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);
Expand Down
22 changes: 22 additions & 0 deletions tests/Unit/Connector/SocketConnectorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace Scoutapm\UnitTests\Connector;

use PHPUnit\Framework\TestCase;
use Scoutapm\Connector\Exception\FailedToConnect;
use Scoutapm\Connector\SocketConnector;

/** @covers \Scoutapm\Connector\SocketConnector */
final class SocketConnectorTest extends TestCase
{
public function testExceptionIsRaisedWhenConnectingToNonExistentSocket() : void
{
$connector = new SocketConnector('/path/does/not/exist');

$this->expectException(FailedToConnect::class);
$this->expectExceptionMessage('socket_connect(): unable to connect [2]: No such file or directory');
$connector->connect();
}
}

0 comments on commit 6226474

Please sign in to comment.