How to catch Exceptions correctly in PHP and MongoDB

My question is about the correct way to catch exceptions in PHP. Based on the accompanying examples of the PHP MongoDB driver, I have created the following script:

<?php

try {

    $mng = new MongoDB\Driver\Manager("mongodb://localhost:2717");
    $query = new MongoDB\Driver\Query([], ['sort' => [ 'name' => 1], 'limit' => 5]);     

    $rows = $mng->executeQuery("testdb.cars", $query);

    foreach ($rows as $row) {

        echo "$row->name : $row->price\n";
    }

} catch (MongoDB\Driver\Exception\Exception $e) {

    $filename = basename(__FILE__);

    echo "The $filename script has experienced an error.\n"; 
    echo "It failed with the following exception:\n";

    echo "Exception:", $e->getMessage(), "\n";
    echo "In file:", $e->getFile(), "\n";
    echo "On line:", $e->getLine(), "\n";       
}

?>

The example is educational and meant to be run on the PHP CLI. In PHP CLI, we get all the exceptions on the console, but for didactic purposes, I wanted to catch exceptions in the try/catch block.

I have seen more Java code than PHP and therefore, catching a generic MongoDB\Driver\Exception\Exception does not look good to me. In Java, we catch specific exceptions and have multiple try/catch blocks for different kinds of exceptions.

The driver has the following Exceptions:

MongoDB\Driver\Exception\AuthenticationException
MongoDB\Driver\Exception\BulkWriteException 
MongoDB\Driver\Exception\ConnectionException 
MongoDB\Driver\Exception\ConnectionTimeoutException 
MongoDB\Driver\Exception\Exception 
MongoDB\Driver\Exception\ExecutionTimeoutException 
MongoDB\Driver\Exception\InvalidArgumentException 
MongoDB\Driver\Exception\LogicException 
MongoDB\Driver\Exception\RuntimeException 
MongoDB\Driver\Exception\SSLConnectionException 
MongoDB\Driver\Exception\UnexpectedValueException 
MongoDB\Driver\Exception\WriteException

Is this a kosher way to catch exceptions in PHP?

You can add multiple catch statements

<?php

try {

    $mng = new MongoDB\Driver\Manager("mongodb://localhost:2717");
    $query = new MongoDB\Driver\Query([], ['sort' => [ 'name' => 1], 'limit' => 5]);     

    $rows = $mng->executeQuery("testdb.cars", $query);

    foreach ($rows as $row) {

        echo "$row->name : $row->price\n";
    }

} catch (MongoDB\Driver\Exception\AuthenticationException $e) {

    echo "Exception:", $e->getMessage(), "\n";
} catch (MongoDB\Driver\Exception\ConnectionException $e) {

    echo "Exception:", $e->getMessage(), "\n";
} catch (MongoDB\Driver\Exception\ConnectionTimeoutException $e) {

    echo "Exception:", $e->getMessage(), "\n";
}

?>

MongoCursorException - Manual, Default Mongo exception. The MongoSomething object has not been correctly initialized by its constructor. Code: 0. Probably will throw an exception. <?php Throw: The throw keyword is used to signal the occurrence of a PHP exception. The PHP runtime will then try to find a catch statement to handle the exception. Catch: This block of code will be called only if an exception occurs within the try code block. The code within your catch statement must handle the exception that was thrown.

How about placing a switch statement in the catch part, and determine the exception's type with the instanceof language construct or the get_class() function?

For example:

[...]

} catch(\Exception $e) {
   switch (get_class($e)) {
     case 'MongoDB\Driver\Exception\AuthenticationException':
       // do stuff
       break;

     case 'MongoDB\Driver\Exception\BulkWriteException':
     //etc, etc...
   }
}

At first, I would examine the return values of get_class(), to make sure you I'm comparing the result with the exact exception names.

MongoException - Manual, This class extends PHP's BadMethodCallException class and implements the library's Exception interface. MongoDB\Exception\InvalidArgumentException. "" can mess up subobject access and is used by MongoDB internally. However, if you really want, you can set mongo.allow_empty_keys to true in your php.ini file to override this sanity check.

Adding multiple catch statement I think it's a better approach than switch. However, what if the exception isn't from these classes with a switch you should have a default case and also if you do it with multiple catches.

try {

$mng = new MongoDB\Driver\Manager("mongodb://localhost:2717");
$query = new MongoDB\Driver\Query([], ['sort' => [ 'name' => 1], 'limit' => 5]);     

$rows = $mng->executeQuery("testdb.cars", $query);

foreach ($rows as $row) {

    echo "$row->name : $row->price\n";
}

} catch (MongoDB\Driver\Exception\AuthenticationException $e) {
    echo "AuthenticationException:", $e->getMessage(), "\n";

} catch (MongoDB\Driver\Exception\ConnectionException $e) {
    echo "ConnectionException:", $e->getMessage(), "\n";

} catch (MongoDB\Driver\Exception\ConnectionTimeoutException $e) {
    echo "ConnectionTimeoutException:", $e->getMessage(), "\n";

}catch (\Exception $e) {
       echo "Exception:", $e->getMessage(), "\n";
}

Exception Classes — PHP Library Manual 1.2, PHP Fatal error: Uncaught exception catch (\MongoDB\Driver\Exception\ RuntimeException $e) { // is not always thrown .. echo Do I understand correctly that you can reproduce it with just the code you've just submitted? Note: . Versions of PHP 5, prior to PHP 5.3.0 do not support nesting of exceptions. The following code fragment can be used as a replacement MyException class if you wish to run this example.

mongodb/mongo-php-library, Get code examples like "how to handle exception in php mongodb in laravel" instantly right from your google search results with the Grepper� Там нет функции findAndModify еще. Вместо findAndModify, вам придется выполнить общую команду базы данных, чтобы сделать это:

how to handle exception in php mongodb in laravel Code Example, Corollary: If you want to catch *any* exception, no matter what the type, just use "catch(Exception $var)", because all exceptions are sub-classes of the built-in Exception.

MongoDB PHP tutorial specially designs to connect MongoDB with PHP. Here, we will see the process with an example for clear understanding. So before wasting time, let’s discuss it.

Comments
  • This is how it is done in Java. The question is if it is the proper way to go. (I did not see code in PHP that way.) And the MongoDB\Driver\Exception\Exception also catches the ConnectionTimeoutException so maybe it is redundat to do it this way.
  • Yes, It is the Java way and same in the PHP. For more information you can see php.net/manual/en/language.exceptions.php. MongoDB\Driver\Exception\Exception is the generic class to catch all the exceptions and must be used as a fallback for exceptions not specifically caught in catch statements.
  • We could do it in such a way, but is this the recommended way to catch exceptions in PHP? If so, why?