PHP – Where Should PDOExceptions Be Dealt With?

exception handlingobject-orientedPHP

I wrote a database wrapper class to help with queries and I'm trying to figure the best way to implement try-catch blocks.

In my database class, I have a helper function;

public function fetchAll($sql, $bind = array()) {

        $stmt = $this->query($sql, $bind);
        $result = $stmt->fetchAll($this->_fetch_mode);

        return $result;
    }

that I can call outside of the class:

$this->db->fetchAll($sql,[$var1,$var2]);

My question is where to put the try-catch blocks. It would be "easier" if I just put them inside of my database class:

    public function fetchAll($sql, $bind = array()) {

            $stmt = $this->query($sql, $bind);
            try {
                  $result = $stmt->fetchAll($this->_fetch_mode);
                } catch (PDOException $e) {
                   //log the error...give some message
                }

            return $result;
        }

instead of wrapping each call to the database class:

try {
     $this->db->fetchAll($sql,[$var1,$var2]);
    } (catch PDOException $e) {
     //log the error...give some message
    }

However, my feeling (without being able to come up with a concrete example…) is that even though it would be more work to wrap each call to the database class, if I do hard code the try-catch block in my database class, it won't be as flexible in terms of handling errors.

Or, would it be better to have a "catch-all" in my index.php (I use MVC) to catch general exceptions (for example, PDO related), and then if I need more specific ones in my application (for example, those thrown when connecting to 3rd party services), then add additional try-block catches for them:

In my index.php, which all requests pass through via my .htaccess file:

try {
    $db = new Db();
    $db->connect(['host'=>DB_HOST,'dbname'=>DB_NAME,'username'=>DB_USERNAME,'password'=>DB_PASSWORD]);

    $bootstrap = new Bootstrap();

    $bootstrap->setControllerPath('application/controllers');
    $bootstrap->setModelPath('application/models');

    $bootstrap->init(); //load the controller/model/classes
} (catch Exception $e) {
    //log error
    //if ajax request return json_encoded message other redirect to error page
}

Best Answer

You shouldn't catch the PDOException at all.

Now, you should have some sort of last resort exception handler that catches all exceptions and logs them. PDOExceptions should be caught there. But you shouldn't catch them anywhere else.

In my understanding, PDOException indicates either that something has gone very wrong with the connection to the database, or you wrote bad SQL. Its only useful to attempt to handle the exception if you can do something useful as an alternative. But if you can't get the information from the database, your application is probably useless, and there is little point in trying to recover.