Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 824
Jan Bodnar Avatar asked Dec 25 '22 06:12

Jan Bodnar


2 Answers

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.

like image 54
Gergely Lukacsy Avatar answered Jan 05 '23 13:01

Gergely Lukacsy


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";
}

?>
like image 35
prabhat Avatar answered Jan 05 '23 12:01

prabhat