Browse Source

Differentiate communication exceptions between connection and protocol exceptions.

Daniele Alessandri 14 years ago
parent
commit
4ea8489110

+ 4 - 4
lib/Predis/CommunicationException.php

@@ -4,15 +4,15 @@ namespace Predis;
 
 use Predis\Network\IConnectionSingle;
 
-class CommunicationException extends PredisException {
+abstract class CommunicationException extends PredisException {
     // Communication errors
     private $_connection;
 
-    public function __construct(IConnectionSingle $connection,
-        $message = null, $code = null) {
+    public function __construct(IConnectionSingle $connection, $message = null,
+        $code = null, \Exception $innerException = null) {
 
         $this->_connection = $connection;
-        parent::__construct($message, $code);
+        parent::__construct($message, $code, $innerException);
     }
 
     public function getConnection() { return $this->_connection; }

+ 7 - 0
lib/Predis/ConnectionException.php

@@ -0,0 +1,7 @@
+<?php
+
+namespace Predis;
+
+class ConnectionException extends CommunicationException {
+    // Network errors
+}

+ 0 - 7
lib/Predis/MalformedServerResponse.php

@@ -1,7 +0,0 @@
-<?php
-
-namespace Predis;
-
-class MalformedServerResponse extends CommunicationException {
-    // Unexpected responses
-}

+ 4 - 8
lib/Predis/MultiExecContext.php

@@ -73,9 +73,7 @@ class MultiExecContext {
         $command  = $client->createCommand($method, $arguments);
         $response = $client->executeCommand($command);
         if (!$response instanceof ResponseQueued) {
-            $this->malformedServerResponse(
-                'The server did not respond with a QUEUED status reply'
-            );
+            $this->onProtocolError('The server did not respond with a QUEUED status reply');
         }
         $this->_commands[] = $command;
         return $this;
@@ -206,9 +204,7 @@ class MultiExecContext {
 
         $commands = &$this->_commands;
         if ($sizeofReplies !== count($commands)) {
-            $this->malformedServerResponse(
-                'Unexpected number of responses for a MultiExecContext'
-            );
+            $this->onProtocolError('Unexpected number of responses for a MultiExecContext');
         }
         for ($i = 0; $i < $sizeofReplies; $i++) {
             $returnValues[] = $commands[$i]->parseResponse($execReply[$i] instanceof \Iterator
@@ -221,11 +217,11 @@ class MultiExecContext {
         return $returnValues;
     }
 
-    private function malformedServerResponse($message) {
+    private function onProtocolError($message) {
         // Since a MULTI/EXEC block cannot be initialized over a clustered
         // connection, we can safely assume that Predis\Client::getConnection()
         // will always return an instance of Predis\Network\IConnectionSingle.
-        Utils::onCommunicationException(new MalformedServerResponse(
+        Utils::onCommunicationException(new ProtocolException(
             $this->_client->getConnection(), $message
         ));
     }

+ 2 - 2
lib/Predis/Network/ComposableStreamConnection.php

@@ -45,7 +45,7 @@ class ComposableStreamConnection extends StreamConnection implements IConnection
         do {
             $chunk = fread($socket, $length);
             if ($chunk === false || $chunk === '') {
-                $this->onCommunicationException('Error while reading bytes from the server');
+                $this->onConnectionError('Error while reading bytes from the server');
             }
             $value .= $chunk;
         }
@@ -59,7 +59,7 @@ class ComposableStreamConnection extends StreamConnection implements IConnection
         do {
             $chunk = fgets($socket);
             if ($chunk === false || $chunk === '') {
-                $this->onCommunicationException('Error while reading line from the server');
+                $this->onConnectionError('Error while reading line from the server');
             }
             $value .= $chunk;
         }

+ 10 - 3
lib/Predis/Network/ConnectionBase.php

@@ -6,7 +6,8 @@ use \InvalidArgumentException;
 use Predis\Utils;
 use Predis\IConnectionParameters;
 use Predis\ClientException;
-use Predis\CommunicationException;
+use Predis\ProtocolException;
+use Predis\ConnectionException;
 use Predis\Commands\ICommand;
 
 abstract class ConnectionBase implements IConnectionSingle {
@@ -79,9 +80,15 @@ abstract class ConnectionBase implements IConnectionSingle {
         return $command->parseResponse($reply);
     }
 
-    protected function onCommunicationException($message, $code = null) {
+    protected function onConnectionError($message, $code = null) {
         Utils::onCommunicationException(
-            new CommunicationException($this, $message, $code)
+            new ConnectionException($this, $message, $code)
+        );
+    }
+
+    protected function onProtocolError($message) {
+        Utils::onCommunicationException(
+            new ProtocolException($this, $message)
         );
     }
 

+ 6 - 6
lib/Predis/Network/PhpiredisConnection.php

@@ -98,7 +98,7 @@ class PhpiredisConnection extends ConnectionBase {
         $errno  = socket_last_error();
         $errstr = socket_strerror($errno);
         $this->disconnect();
-        $this->onCommunicationException(trim($errstr), $errno);
+        $this->onConnectionError(trim($errstr), $errno);
     }
 
     protected function createResource() {
@@ -156,7 +156,7 @@ class PhpiredisConnection extends ConnectionBase {
         $host = $parameters->host;
         if (ip2long($host) === false) {
             if (($address = gethostbyname($host)) === $host) {
-                $this->onCommunicationException("Cannot resolve the address of $host");
+                $this->onConnectionError("Cannot resolve the address of $host");
             }
             return $address;
         }
@@ -183,10 +183,10 @@ class PhpiredisConnection extends ConnectionBase {
 
         $selected = socket_select($selectable, $selectable, $null, $timeoutSecs, $timeoutUSecs);
         if ($selected === 2) {
-            $this->onCommunicationException('Connection refused', SOCKET_ECONNREFUSED);
+            $this->onConnectionError('Connection refused', SOCKET_ECONNREFUSED);
         }
         if ($selected === 0) {
-            $this->onCommunicationException('Connection timed out', SOCKET_ETIMEDOUT);
+            $this->onConnectionError('Connection timed out', SOCKET_ETIMEDOUT);
         }
         if ($selected === false) {
             $this->emitSocketError();
@@ -225,7 +225,7 @@ class PhpiredisConnection extends ConnectionBase {
                 return;
             }
             if ($written === false) {
-                $this->onCommunicationException('Error while writing bytes to the server');
+                $this->onConnectionError('Error while writing bytes to the server');
             }
             $buffer = substr($buffer, $written);
         }
@@ -244,7 +244,7 @@ class PhpiredisConnection extends ConnectionBase {
             return phpiredis_reader_get_reply($reader);
         }
         else {
-            $this->onCommunicationException(phpiredis_reader_get_error($reader));
+            $this->onProtocolError(phpiredis_reader_get_error($reader));
         }
     }
 

+ 6 - 11
lib/Predis/Network/StreamConnection.php

@@ -6,7 +6,6 @@ use Predis\ResponseError;
 use Predis\ResponseQueued;
 use Predis\ServerException;
 use Predis\IConnectionParameters;
-use Predis\CommunicationException;
 use Predis\Commands\ICommand;
 use Predis\Protocols\TextCommandSerializer;
 use Predis\Iterators\MultiBulkResponseSimple;
@@ -44,7 +43,7 @@ class StreamConnection extends ConnectionBase {
             $uri, $errno, $errstr, $parameters->connection_timeout, $flags
         );
         if (!$resource) {
-            $this->onCommunicationException(trim($errstr), $errno);
+            $this->onConnectionError(trim($errstr), $errno);
         }
         if (isset($parameters->read_write_timeout)) {
             $rwtimeout = $parameters->read_write_timeout;
@@ -66,7 +65,7 @@ class StreamConnection extends ConnectionBase {
             $uri, $errno, $errstr, $parameters->connection_timeout, $flags
         );
         if (!$resource) {
-            $this->onCommunicationException(trim($errstr), $errno);
+            $this->onConnectionError(trim($errstr), $errno);
         }
         return $resource;
     }
@@ -102,9 +101,7 @@ class StreamConnection extends ConnectionBase {
                 return;
             }
             if ($written === false || $written === 0) {
-                $this->onCommunicationException(
-                    'Error while writing bytes to the server'
-                );
+                $this->onConnectionError('Error while writing bytes to the server');
             }
             $value = substr($buffer, $written);
         }
@@ -114,9 +111,7 @@ class StreamConnection extends ConnectionBase {
         $socket = $this->getResource();
         $chunk  = fgets($socket);
         if ($chunk === false || $chunk === '') {
-            $this->onCommunicationException(
-                'Error while reading line from the server'
-            );
+            $this->onConnectionError('Error while reading line from the server');
         }
         $prefix  = $chunk[0];
         $payload = substr($chunk, 1, -2);
@@ -141,7 +136,7 @@ class StreamConnection extends ConnectionBase {
                 do {
                     $chunk = fread($socket, min($bytesLeft, 4096));
                     if ($chunk === false || $chunk === '') {
-                        $this->onCommunicationException(
+                        $this->onConnectionError(
                             'Error while reading bytes from the server'
                         );
                     }
@@ -175,7 +170,7 @@ class StreamConnection extends ConnectionBase {
                 return new ResponseError($errorMessage);
 
             default:
-                $this->onCommunicationException("Unknown prefix: '$prefix'");
+                $this->onProtocolError("Unknown prefix: '$prefix'");
         }
     }
 

+ 13 - 0
lib/Predis/ProtocolException.php

@@ -0,0 +1,13 @@
+<?php
+
+namespace Predis;
+
+use Predis\Network\IConnectionSingle;
+
+class ProtocolException extends CommunicationException {
+    // Unexpected responses
+
+    public function __construct(IConnectionSingle $connection, $message = null) {
+        parent::__construct($connection, $message);
+    }
+}

+ 2 - 3
lib/Predis/Protocols/ResponseBulkHandler.php

@@ -3,15 +3,14 @@
 namespace Predis\Protocols;
 
 use Predis\Utils;
-use Predis\CommunicationException;
-use Predis\MalformedServerResponse;
+use Predis\ProtocolException;
 use Predis\Network\IConnectionComposable;
 
 class ResponseBulkHandler implements IResponseHandler {
     public function handle(IConnectionComposable $connection, $lengthString) {
         $length = (int) $lengthString;
         if ($length != $lengthString) {
-            Utils::onCommunicationException(new MalformedServerResponse(
+            Utils::onCommunicationException(new ProtocolException(
                 $connection, "Cannot parse '$length' as data length"
             ));
         }

+ 2 - 2
lib/Predis/Protocols/ResponseIntegerHandler.php

@@ -3,7 +3,7 @@
 namespace Predis\Protocols;
 
 use Predis\Utils;
-use Predis\MalformedServerResponse;
+use Predis\ProtocolException;
 use Predis\Network\IConnectionComposable;
 
 class ResponseIntegerHandler implements IResponseHandler {
@@ -12,7 +12,7 @@ class ResponseIntegerHandler implements IResponseHandler {
             return (int) $number;
         }
         if ($number !== 'nil') {
-            Utils::onCommunicationException(new MalformedServerResponse(
+            Utils::onCommunicationException(new ProtocolException(
                 $connection, "Cannot parse '$number' as numeric response"
             ));
         }

+ 2 - 2
lib/Predis/Protocols/ResponseMultiBulkHandler.php

@@ -3,14 +3,14 @@
 namespace Predis\Protocols;
 
 use Predis\Utils;
-use Predis\MalformedServerResponse;
+use Predis\ProtocolException;
 use Predis\Network\IConnectionComposable;
 
 class ResponseMultiBulkHandler implements IResponseHandler {
     public function handle(IConnectionComposable $connection, $lengthString) {
         $length = (int) $lengthString;
         if ($length != $lengthString) {
-            Utils::onCommunicationException(new MalformedServerResponse(
+            Utils::onCommunicationException(new ProtocolException(
                 $connection, "Cannot parse '$length' as data length"
             ));
         }

+ 2 - 2
lib/Predis/Protocols/ResponseMultiBulkStreamHandler.php

@@ -3,7 +3,7 @@
 namespace Predis\Protocols;
 
 use Predis\Utils;
-use Predis\MalformedServerResponse;
+use Predis\ProtocolException;
 use Predis\Network\IConnectionComposable;
 use Predis\Iterators\MultiBulkResponseSimple;
 
@@ -11,7 +11,7 @@ class ResponseMultiBulkStreamHandler implements IResponseHandler {
     public function handle(IConnectionComposable $connection, $lengthString) {
         $length = (int) $lengthString;
         if ($length != $lengthString) {
-            Utils::onCommunicationException(new MalformedServerResponse(
+            Utils::onCommunicationException(new ProtocolException(
                 $connection, "Cannot parse '$length' as data length"
             ));
         }

+ 3 - 3
lib/Predis/Protocols/TextProtocol.php

@@ -5,7 +5,7 @@ namespace Predis\Protocols;
 use Predis\ResponseError;
 use Predis\ResponseQueued;
 use Predis\ServerException;
-use Predis\CommunicationException;
+use Predis\ProtocolException;
 use Predis\Commands\ICommand;
 use Predis\Network\IConnectionComposable;
 use Predis\Iterators\MultiBulkResponseSimple;
@@ -84,9 +84,9 @@ class TextProtocol implements IProtocolProcessor {
                 return new ResponseError($errorMessage);
 
             default:
-                throw new CommunicationException(
+                Utils::onCommunicationException(new ProtocolException(
                     $connection, "Unknown prefix: '$prefix'"
-                );
+                ));
         }
     }
 

+ 4 - 7
lib/Predis/Protocols/TextResponseReader.php

@@ -3,8 +3,7 @@
 namespace Predis\Protocols;
 
 use Predis\Utils;
-use Predis\CommunicationException;
-use Predis\MalformedServerResponse;
+use Predis\ProtocolException;
 use Predis\Network\IConnectionComposable;
 
 class TextResponseReader implements IResponseReader {
@@ -37,7 +36,7 @@ class TextResponseReader implements IResponseReader {
     public function read(IConnectionComposable $connection) {
         $header = $connection->readLine();
         if ($header === '') {
-            $this->throwMalformedResponse($connection, 'Unexpected empty header');
+            $this->protocolError($connection, 'Unexpected empty header');
         }
 
         $prefix = $header[0];
@@ -48,9 +47,7 @@ class TextResponseReader implements IResponseReader {
         return $handler->handle($connection, substr($header, 1));
     }
 
-    private function throwMalformedResponse(IConnectionComposable $connection, $message) {
-        Utils::onCommunicationException(new MalformedServerResponse(
-            $connection, $message
-        ));
+    private function protocolError(IConnectionComposable $connection, $message) {
+        Utils::onCommunicationException(new ProtocolException($connection, $message));
     }
 }