Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I throw Exceptions in own Database class with PDO?

Hey I have Database class with PDO and some other classes for an object oriented forum:

class Database {

    private $databaseConnection;

    function __construct($path = "", $dbUsername = "", $dbPassword = ""){
        $parts = explode('.',$path);
        $documentType = array_pop($parts);

        if(($path == "") || ((strcmp($documentType, "sq3") !== 0) && (strcmp($documentType, "sqlite") !== 0))) {
            throw new Exception("The Database must bee .sq3 or .sqlite and Path must be stated");
        }

        $this->databaseConnection = new PDO('sqlite:' . $path, $dbUsername, $dbPassword);
        $this->databaseConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $this->databaseConnection->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);

        self::query('CREATE TABLE...)');
    }

    function query($sql, $params = NULL){
    ...
    }

    function getObjects($objectTable, $searchedForAttribute, $attributeValue){
    ...
    }


    function insertObject($object){
    ...
    }

    function updateObject($object){
    ...
    }

    function removeObject($object){
    ...
    }

    ...//some other methods

    function __destruct(){
        unset($this->databaseConnection);
    }
}

Should I use Exceptions ? Such like:

    function insertObject($object){
    try {
       ...
    }catch(PDOException $e){
            throw new Exception($e->getMessage());
         }
    }

As a result I have to catch this Exceptions somewhere else and give it out in a different way. For Example: I have a Class User and a table User. So if a new registration is filled out I have to validate the information for the new User. So if an expactant User choose a name which is already in the Database I would throw an Exception although I only need a message for the User which says that the name is already assigned.

So I thought it would be better if I do something like:

    function insertObject($object){
    try {
       ...
    }catch(PDOException $e){
            return "Username already assigned";
         }
    }

Of course I do not always know why an Exception gets thrown but in such a case I would validate datas with an if-block.

So how should I use Exception handling in this case?

like image 395
goulashsoup Avatar asked Mar 23 '26 10:03

goulashsoup


1 Answers

Your question is simple, and yet quite vast all at the same time (IMHO).

Firstly I'd recommend you grab something like Doctrine or another good off-the-shelf ORM package if you want a "simple database abstraction through ORM/models". Or a framework.

If (like me) you're a real sucker for doing things from scratch like this, then I've a few suggestions from painful prior experiences.

  1. Returning strings (like you suggest at the end of your question) is a Really Bad Idea(TM). Strings are good for stringy things - not defined responses from one piece of code to another like this. Defined constants (using, let's say, integer values) is better for this route - IMHO.
  2. Exceptions make a lot of sense here - you wish to say "I failed to do what you asked of me, I need you to handle it".

If you choose to go down the exception route (I'm pro both - coming from a C/C++ background originally) use string values for the stringy bits (give the exception a human-friendly message to display) and also give it a machine-friendly attribute too (for the code which will capture it).

\PDOException makes natural sense to state that a database failure just occurred, like "I lost connectivity" or "MySQL borked". You might wish to just let those exceptions raise themselves back to the code calling yours...

For your model-specific errors, I'd create appropriate exception classes. Literally:

class UserModelException extends \Exception {
 ... // Optional stuff here
}

Then you can catch different sorts of errors in the calling code:

try {
 ...
} catch (\UserModelException $e) {
 ...
} catch (\PDOException $e) {
 ...
}

Etc.

Of course you might want to catch the PDO exceptions in your model to determine if something like a unique key constraint just blew up - i.e. indicating that the username already exists. In this situation you might (in your model) want to:

try {
 ...
} catch (\PDOException $e) {
   if (...) { // unique constraint error - username already taken
      throw new \UserModelException(...);
   } else {
      throw $e;
   }
}

Does that in any way make sense, and is it in any way helpful?

I can't think (off the top of my head) a situation that I'd recommend throwing a literal \Exception object - I'd always inherit it on a per-context basis.

like image 112
wally Avatar answered Mar 26 '26 00:03

wally



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!