Просмотр исходного кода

Add exception handling to MongoClient

Olivier Lechevalier 10 лет назад
Родитель
Сommit
71fc145a2b

+ 17 - 5
lib/Mongo/MongoClient.php

@@ -14,6 +14,7 @@
  */
 
 use Alcaeus\MongoDbAdapter\Helper;
+use Alcaeus\MongoDbAdapter\ExceptionConverter;
 use MongoDB\Client;
 
 /**
@@ -182,8 +183,15 @@ class MongoClient
     {
         $this->forceConnect();
 
-        $servers = [];
-        foreach ($this->manager->getServers() as $server) {
+        $results = [];
+
+        try {
+            $servers = $this->manager->getServers();
+        } catch (\MongoDB\Driver\Exception\Exception $e) {
+            ExceptionConverter::toLegacy($e);
+        }
+
+        foreach ($servers as $server) {
             $key = sprintf('%s:%d', $server->getHost(), $server->getPort());
             $info = $server->getInfo();
 
@@ -198,7 +206,7 @@ class MongoClient
                     $state = 0;
             }
 
-            $servers[$key] = [
+            $results[$key] = [
                 'host' => $server->getHost(),
                 'port' => $server->getPort(),
                 'health' => (int) $info['ok'],
@@ -208,7 +216,7 @@ class MongoClient
             ];
         }
 
-        return $servers;
+        return $results;
     }
 
     /**
@@ -232,7 +240,11 @@ class MongoClient
      */
     public function listDBs()
     {
-        $databaseInfoIterator = $this->client->listDatabases();
+        try {
+            $databaseInfoIterator = $this->client->listDatabases();
+        } catch (\MongoDB\Driver\Exception\Exception $e) {
+            ExceptionConverter::toLegacy($e);
+        }
 
         $databases = [
             'databases' => [],

+ 0 - 3
lib/Mongo/MongoCollection.php

@@ -539,9 +539,6 @@ class MongoCollection
         try {
             $document = $this->collection->findOne(TypeConverter::fromLegacy($query), $options);
         } catch (\MongoDB\Driver\Exception\Exception $e) {
-            if (strpos($e->getMessage(), 'No suitable servers found') !== false) {
-                throw new MongoConnectionException($e->getMessage(), $e->getCode(), $e);
-            }
             ExceptionConverter::toLegacy($e);
         }
 

+ 22 - 0
lib/Mongo/MongoDB.php

@@ -59,6 +59,7 @@ class MongoDB
      */
     public function __construct(MongoClient $conn, $name)
     {
+        $this->checkDatabaseName($name);
         $this->connection = $conn;
         $this->name = $name;
 
@@ -495,4 +496,25 @@ class MongoDB
             $this->db = $this->db->withOptions($options);
         }
     }
+
+    private function checkDatabaseName($name)
+    {
+        if (empty($name)) {
+            throw new \Exception('Database name cannot be empty');
+        }
+        if (strlen($name) >= 64) {
+            throw new \Exception('Database name cannot exceed 63 characters');
+        }
+        if (strpos($name, chr(0)) !== false) {
+            throw new \Exception('Database name cannot contain null bytes');
+        }
+
+        $invalidCharacters = ['.', '$', '/', ' ', '\\'];
+        foreach ($invalidCharacters as $char) {
+            if (strchr($name, $char) !== false) {
+                throw new \Exception('Database name contains invalid characters');
+            }
+        }
+
+    }
 }

+ 14 - 0
tests/Alcaeus/MongoDbAdapter/MongoClientTest.php

@@ -30,6 +30,20 @@ class MongoClientTest extends TestCase
         $this->assertSame('mongo-php-adapter', (string) $db);
     }
 
+    public function testSelectDBWithEmptyName()
+    {
+        $this->setExpectedException('Exception', 'Database name cannot be empty');
+
+        $this->getClient()->selectDB('');
+    }
+
+    public function testSelectDBWithInvalidName()
+    {
+        $this->setExpectedException('Exception', 'Database name contains invalid characters');
+
+        $this->getClient()->selectDB('/');
+    }
+
     public function testGetDbProperty()
     {
         $client = $this->getClient();

+ 14 - 0
tests/Alcaeus/MongoDbAdapter/MongoDBTest.php

@@ -8,6 +8,20 @@ use MongoDB\Driver\ReadPreference;
  */
 class MongoDBTest extends TestCase
 {
+    public function testEmptyDatabaseName()
+    {
+        $this->setExpectedException('Exception', 'Database name cannot be empty');
+
+        new \MongoDB($this->getClient(), '');
+    }
+
+    public function testInvalidDatabaseName()
+    {
+        $this->setExpectedException('Exception', 'Database name contains invalid characters');
+
+        new \MongoDB($this->getClient(), '/');
+    }
+
     public function testGetCollection()
     {
         $db = $this->getDatabase();