user3057514
user3057514

Reputation: 261

How to handler errors in abstract class PDO

I have an abstract classes for update, select, delete and insert statements. in my database connection function, config.php I have

function dbconnect() 
{
            $dbh; // database handler
             $host = 'localhost';
             $user =  'root';
             $pass =  '';
             $dbname = '';
             $error;


                // Set DSN
                $dsn = 'mysql:host=' . $host . ';dbname=' . $dbname;
                // Set options
                $options = array(
                    PDO::ATTR_PERSISTENT    => true,
                    PDO::ATTR_ERRMODE       => PDO::ERRMODE_EXCEPTION,
                    PDO::ATTR_EMULATE_PREPARES => false

                );
                // Create a new PDO instanace
                try{
                    $dbh = new PDO($dsn, $user, $pass, $options);
                }
                // Catch any errors
                catch(PDOException $e){
                    $error = $e->getMessage();
                }

               return $dbh;
           }     

notice try catch an error

in my abstract class.

   public function __construct() {
           $this->dbh = dbconnect();

       }

       public function query($query) {
           $this->stmt = $this->dbh->prepare($query);
       }

       public function bind($param, $value, $type = null) {
           if(is_null($type)) {
               switch (true) {
                   case is_int($value):
                       $type = PD0::PARAM_INT;
                       break;
                    case is_bool($value);
                        $type = PDO::PARAM_BOOL;
                        break;
                    case is_null($value);
                        $type = PDO::PARAM_NULL;
                        break;
                    default :
                        $type = PDO::PARAM_STR;
               }
           }
           $this->stmt->bindValue($param, $value, $type);
       }
 }

My question

In the construct I connect to the database which also means I am catching errors here and in the other function I have not error handling and I am not returning any errors in it. Is they any point in me having error handle in other functions I have and if yes how do you suggest I handle this? I am still need to PDO and OOP in general but I do try to do things the right way. Please advice

Upvotes: 1

Views: 723

Answers (2)

CD001
CD001

Reputation: 8482

The only time you might need to handle an Exception in a constructor for a database wrapper is to ensure a particular type of Exception is thrown and bubbled up to the application - though I can only see this being useful if you're building a wrapper that can switch database connection objects.

If you're using a Factory pattern for instance that can create either a mysqli or a PDO object you might want the constructor to catch mysqli::connect_error (not an Excepton) AND PDOException and always throw a common AppException (which extends Exception).

So in the mysqli constructor you might simply have:

$dbConn = new mysqli($sHost, $sUsername, $sPassword, $sSchema, $iPort);

if($dbConn->connect_error) {
  throw new AppExecption(AppException::DB_CONNECT, $dbConn->connect_error);
}

Whilst in the PDO wrapper constructor you might have:

try {
  $dbConn = new PDO($sDSN, $sUsername, $sPassword);
}

catch(PDOException $e) {
  throw new AppException(AppException::DB_CONNECT, $e->getMessage());
}

So you're not really handling the PDOException in the constructor - merely converting it into a common type of Exception which could be handled in a specific way when it's bubbled up to the application irrespective as to whether you're constructing a mysqli object or a PDO one.

Upvotes: 0

deceze
deceze

Reputation: 522597

Basically, if you cannot connect to the database, there's no point in having any of the other code, right? Then simply do not catch the exception. The exception will bubble up and even prevent your class from being instantiated, which means you do not need to worry about error handling in any of the other code because it can never be executed. That's the point of throwing exceptions in constructors.

Exceptions are for signalling exceptional circumstances. If you cannot connect to the database, that's quite an exceptional circumstance. That renders your entire database layer non-functional. Throwing an exception from the database layer is the correct thing to do here, because the database layer is non-operational and cannot handle this problem itself. It needs to signal to the rest of the system that it cannot work and the rest of the system needs to decide what to do in this case. Catch the exception higher up in your app, if at all, and react to it by displaying an error page there.

For other exceptions which may happen during regular queries, the same rule applies. Decide whether the problem is recoverable and whether it makes sense to catch and handle it inside your database class, or whether an exception (which, again, is something which should never ever happen) means it's time to give up.

Upvotes: 3

Related Questions