Add more specific exceptions
This commit is contained in:
@ -5,10 +5,13 @@ declare(strict_types=1);
|
|||||||
namespace Nsq;
|
namespace Nsq;
|
||||||
|
|
||||||
use Composer\InstalledVersions;
|
use Composer\InstalledVersions;
|
||||||
|
use Nsq\Exception\ConnectionFail;
|
||||||
|
use Nsq\Exception\UnexpectedResponse;
|
||||||
use PHPinnacle\Buffer\ByteBuffer;
|
use PHPinnacle\Buffer\ByteBuffer;
|
||||||
use Psr\Log\LoggerAwareTrait;
|
use Psr\Log\LoggerAwareTrait;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
use Psr\Log\NullLogger;
|
use Psr\Log\NullLogger;
|
||||||
|
use Socket\Raw\Exception;
|
||||||
use Socket\Raw\Factory;
|
use Socket\Raw\Factory;
|
||||||
use Socket\Raw\Socket;
|
use Socket\Raw\Socket;
|
||||||
use Throwable;
|
use Throwable;
|
||||||
@ -65,7 +68,12 @@ abstract class Connection
|
|||||||
|
|
||||||
public function connect(): void
|
public function connect(): void
|
||||||
{
|
{
|
||||||
|
try {
|
||||||
$this->socket = (new Factory())->createClient($this->address);
|
$this->socket = (new Factory())->createClient($this->address);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
throw ConnectionFail::fromThrowable($e);
|
||||||
|
}
|
||||||
|
|
||||||
$this->send(' V2');
|
$this->send(' V2');
|
||||||
|
|
||||||
$body = json_encode($this->features, JSON_THROW_ON_ERROR | JSON_FORCE_OBJECT);
|
$body = json_encode($this->features, JSON_THROW_ON_ERROR | JSON_FORCE_OBJECT);
|
||||||
@ -121,12 +129,12 @@ abstract class Connection
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
$socket->write($buffer);
|
$socket->write($buffer);
|
||||||
} catch (Throwable $e) {
|
} catch (Exception $e) {
|
||||||
$this->closed = true;
|
$this->closed = true;
|
||||||
|
|
||||||
$this->logger->error($e->getMessage(), ['exception' => $e]);
|
$this->logger->error($e->getMessage(), ['exception' => $e]);
|
||||||
|
|
||||||
throw $e;
|
throw ConnectionFail::fromThrowable($e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
@ -162,7 +170,7 @@ abstract class Connection
|
|||||||
$response = $this->receive(0.1);
|
$response = $this->receive(0.1);
|
||||||
|
|
||||||
if (null === $response) {
|
if (null === $response) {
|
||||||
throw new Exception('Response was expected, but null received.');
|
throw new UnexpectedResponse('Response was expected, but null received.');
|
||||||
}
|
}
|
||||||
|
|
||||||
return $response;
|
return $response;
|
||||||
@ -171,7 +179,7 @@ abstract class Connection
|
|||||||
private function socket(): Socket
|
private function socket(): Socket
|
||||||
{
|
{
|
||||||
if ($this->closed) {
|
if ($this->closed) {
|
||||||
throw new Exception('This connection is closed, create new one.');
|
throw new ConnectionFail('This connection is closed, create new one.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null === $this->socket) {
|
if (null === $this->socket) {
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Nsq;
|
|
||||||
|
|
||||||
final class Exception extends \RuntimeException implements NsqException
|
|
||||||
{
|
|
||||||
}
|
|
16
src/Exception/ConnectionFail.php
Normal file
16
src/Exception/ConnectionFail.php
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Nsq\Exception;
|
||||||
|
|
||||||
|
use RuntimeException;
|
||||||
|
use Throwable;
|
||||||
|
|
||||||
|
final class ConnectionFail extends RuntimeException implements NsqException
|
||||||
|
{
|
||||||
|
public static function fromThrowable(Throwable $throwable): self
|
||||||
|
{
|
||||||
|
return new self($throwable->getMessage(), (int) $throwable->getCode(), $throwable);
|
||||||
|
}
|
||||||
|
}
|
26
src/Exception/MessageAlreadyFinished.php
Normal file
26
src/Exception/MessageAlreadyFinished.php
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Nsq\Exception;
|
||||||
|
|
||||||
|
use Nsq\Message;
|
||||||
|
use RuntimeException;
|
||||||
|
|
||||||
|
final class MessageAlreadyFinished extends RuntimeException implements NsqException
|
||||||
|
{
|
||||||
|
public static function finish(Message $message): self
|
||||||
|
{
|
||||||
|
return new self('Can\'t finish message as it already finished.');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function requeue(Message $message): self
|
||||||
|
{
|
||||||
|
return new self('Can\'t requeue message as it already finished.');
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function touch(Message $message): self
|
||||||
|
{
|
||||||
|
return new self('Can\'t touch message as it already finished.');
|
||||||
|
}
|
||||||
|
}
|
11
src/Exception/NsqError.php
Normal file
11
src/Exception/NsqError.php
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Nsq\Exception;
|
||||||
|
|
||||||
|
use RuntimeException;
|
||||||
|
|
||||||
|
final class NsqError extends RuntimeException implements NsqException
|
||||||
|
{
|
||||||
|
}
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace Nsq;
|
namespace Nsq\Exception;
|
||||||
|
|
||||||
use Throwable;
|
use Throwable;
|
||||||
|
|
11
src/Exception/UnexpectedResponse.php
Normal file
11
src/Exception/UnexpectedResponse.php
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Nsq\Exception;
|
||||||
|
|
||||||
|
use RuntimeException;
|
||||||
|
|
||||||
|
final class UnexpectedResponse extends RuntimeException implements NsqException
|
||||||
|
{
|
||||||
|
}
|
@ -4,6 +4,8 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Nsq;
|
namespace Nsq;
|
||||||
|
|
||||||
|
use Nsq\Exception\MessageAlreadyFinished;
|
||||||
|
|
||||||
final class Message
|
final class Message
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@ -48,7 +50,7 @@ final class Message
|
|||||||
public function finish(): void
|
public function finish(): void
|
||||||
{
|
{
|
||||||
if ($this->finished) {
|
if ($this->finished) {
|
||||||
throw new Exception('Can\'t finish message as it already finished.');
|
throw MessageAlreadyFinished::finish($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->consumer->fin($this->id);
|
$this->consumer->fin($this->id);
|
||||||
@ -58,7 +60,7 @@ final class Message
|
|||||||
public function requeue(int $timeout): void
|
public function requeue(int $timeout): void
|
||||||
{
|
{
|
||||||
if ($this->finished) {
|
if ($this->finished) {
|
||||||
throw new Exception('Can\'t requeue message as it already finished.');
|
throw MessageAlreadyFinished::requeue($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->consumer->req($this->id, $timeout);
|
$this->consumer->req($this->id, $timeout);
|
||||||
@ -68,7 +70,7 @@ final class Message
|
|||||||
public function touch(): void
|
public function touch(): void
|
||||||
{
|
{
|
||||||
if ($this->finished) {
|
if ($this->finished) {
|
||||||
throw new Exception('Can\'t touch message as it already finished.');
|
throw MessageAlreadyFinished::touch($this);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->consumer->touch($this->id);
|
$this->consumer->touch($this->id);
|
||||||
|
@ -4,6 +4,8 @@ declare(strict_types=1);
|
|||||||
|
|
||||||
namespace Nsq;
|
namespace Nsq;
|
||||||
|
|
||||||
|
use Nsq\Exception\NsqError;
|
||||||
|
use Nsq\Exception\UnexpectedResponse;
|
||||||
use PHPinnacle\Buffer\ByteBuffer;
|
use PHPinnacle\Buffer\ByteBuffer;
|
||||||
|
|
||||||
final class Response
|
final class Response
|
||||||
@ -27,15 +29,15 @@ final class Response
|
|||||||
public function okOrFail(): void
|
public function okOrFail(): void
|
||||||
{
|
{
|
||||||
if (self::TYPE_ERROR === $this->type) {
|
if (self::TYPE_ERROR === $this->type) {
|
||||||
throw new Exception($this->buffer->bytes());
|
throw new NsqError($this->buffer->bytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self::TYPE_RESPONSE !== $this->type) {
|
if (self::TYPE_RESPONSE !== $this->type) {
|
||||||
throw new Exception(sprintf('"%s" type expected, but "%s" received.', self::TYPE_RESPONSE, $this->type));
|
throw new UnexpectedResponse(sprintf('"%s" type expected, but "%s" received.', self::TYPE_RESPONSE, $this->type));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self::OK !== $this->buffer->bytes()) {
|
if (self::OK !== $this->buffer->bytes()) {
|
||||||
throw new Exception(sprintf('OK response expected, but "%s" received.', $this->buffer->bytes()));
|
throw new UnexpectedResponse(sprintf('OK response expected, but "%s" received.', $this->buffer->bytes()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,7 +49,7 @@ final class Response
|
|||||||
public function toMessage(Consumer $reader): Message
|
public function toMessage(Consumer $reader): Message
|
||||||
{
|
{
|
||||||
if (self::TYPE_MESSAGE !== $this->type) {
|
if (self::TYPE_MESSAGE !== $this->type) {
|
||||||
throw new Exception(sprintf('Expecting "%s" type, but NSQ return: "%s"', self::TYPE_MESSAGE, $this->type));
|
throw new UnexpectedResponse(sprintf('Expecting "%s" type, but NSQ return: "%s"', self::TYPE_MESSAGE, $this->type));
|
||||||
}
|
}
|
||||||
|
|
||||||
$buffer = new ByteBuffer($this->buffer->bytes());
|
$buffer = new ByteBuffer($this->buffer->bytes());
|
||||||
|
@ -5,6 +5,7 @@ declare(strict_types=1);
|
|||||||
namespace Nsq;
|
namespace Nsq;
|
||||||
|
|
||||||
use Generator;
|
use Generator;
|
||||||
|
use InvalidArgumentException;
|
||||||
use function get_debug_type;
|
use function get_debug_type;
|
||||||
use function sprintf;
|
use function sprintf;
|
||||||
|
|
||||||
@ -41,7 +42,7 @@ final class Subscriber
|
|||||||
$newTimeout = yield null;
|
$newTimeout = yield null;
|
||||||
|
|
||||||
if (!\is_float($newTimeout)) {
|
if (!\is_float($newTimeout)) {
|
||||||
throw new Exception(sprintf('Timeout must be float, "%s" given.', get_debug_type($newTimeout)));
|
throw new InvalidArgumentException(sprintf('Timeout must be float, "%s" given.', get_debug_type($newTimeout)));
|
||||||
}
|
}
|
||||||
|
|
||||||
$timeout = $newTimeout;
|
$timeout = $newTimeout;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
use Nsq\Consumer;
|
use Nsq\Consumer;
|
||||||
use Nsq\Exception;
|
use Nsq\Exception\MessageAlreadyFinished;
|
||||||
use Nsq\Message;
|
use Nsq\Message;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
@ -20,7 +20,7 @@ final class MessageTest extends TestCase
|
|||||||
|
|
||||||
self::assertTrue($message->isFinished());
|
self::assertTrue($message->isFinished());
|
||||||
|
|
||||||
$this->expectException(Exception::class);
|
$this->expectException(MessageAlreadyFinished::class);
|
||||||
$this->expectExceptionMessage('Can\'t finish message as it already finished.');
|
$this->expectExceptionMessage('Can\'t finish message as it already finished.');
|
||||||
|
|
||||||
$message->finish();
|
$message->finish();
|
||||||
@ -37,7 +37,7 @@ final class MessageTest extends TestCase
|
|||||||
|
|
||||||
self::assertTrue($message->isFinished());
|
self::assertTrue($message->isFinished());
|
||||||
|
|
||||||
$this->expectException(Exception::class);
|
$this->expectException(MessageAlreadyFinished::class);
|
||||||
$this->expectExceptionMessage('Can\'t requeue message as it already finished.');
|
$this->expectExceptionMessage('Can\'t requeue message as it already finished.');
|
||||||
|
|
||||||
$message->requeue(5);
|
$message->requeue(5);
|
||||||
@ -52,7 +52,7 @@ final class MessageTest extends TestCase
|
|||||||
|
|
||||||
$message->finish();
|
$message->finish();
|
||||||
|
|
||||||
$this->expectException(Exception::class);
|
$this->expectException(MessageAlreadyFinished::class);
|
||||||
$this->expectExceptionMessage('Can\'t touch message as it already finished.');
|
$this->expectExceptionMessage('Can\'t touch message as it already finished.');
|
||||||
|
|
||||||
$message->touch();
|
$message->touch();
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
declare(strict_types=1);
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
use Nsq\Exception\NsqError;
|
||||||
use Nsq\Producer;
|
use Nsq\Producer;
|
||||||
use PHPUnit\Framework\TestCase;
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
@ -12,7 +13,7 @@ final class ProducerTest extends TestCase
|
|||||||
*/
|
*/
|
||||||
public function testPubFail(string $topic, string $body, string $exceptionMessage): void
|
public function testPubFail(string $topic, string $body, string $exceptionMessage): void
|
||||||
{
|
{
|
||||||
$this->expectException(Exception::class);
|
$this->expectException(NsqError::class);
|
||||||
$this->expectExceptionMessage($exceptionMessage);
|
$this->expectExceptionMessage($exceptionMessage);
|
||||||
|
|
||||||
$producer = new Producer('tcp://localhost:4150');
|
$producer = new Producer('tcp://localhost:4150');
|
||||||
|
@ -34,7 +34,7 @@ final class SubscriberTest extends TestCase
|
|||||||
|
|
||||||
public function testInvalidChangeInterval(): void
|
public function testInvalidChangeInterval(): void
|
||||||
{
|
{
|
||||||
$this->expectException(\Nsq\Exception::class);
|
$this->expectException(InvalidArgumentException::class);
|
||||||
$this->expectExceptionMessage('Timeout must be float, "string" given.');
|
$this->expectExceptionMessage('Timeout must be float, "string" given.');
|
||||||
|
|
||||||
$generator = $this->subscriber->subscribe(__FUNCTION__, __FUNCTION__);
|
$generator = $this->subscriber->subscribe(__FUNCTION__, __FUNCTION__);
|
||||||
|
Reference in New Issue
Block a user