0

Okay so I've been working on a database class and was told to use exception. However I read on the Apple developer guide to avoid exceptions as much as possible and use NSError instead. (https://developer.apple.com/library/ios/#DOCUMENTATION/Cocoa/Conceptual/ObjectiveC/Chapters/ocExceptionHandling.html)

So it got me thinking: Am I using the right approach? Should I be using NSErrors in this case?

+(long)insertTrack:(Track *)track Database:(Database *)db {
@try {
sqlite3_exec(db.dataBase, "BEGIN", 0, 0, 0); //Start transaction

const char *sqlTrack = "INSERT INTO ...";
if(sqlite3_prepare_v2(db.dataBase, sqlTrack, -1, &addTrackStatement, NULL) != SQLITE_OK) {
     @throw [NSException exeption....]       
}

//Bind variables
sqlite3_bind_text(...);

if(SQLITE_DONE != sqlite3_step(addTrackStatement)) {
    @throw [NSException exeption....]
}
else {
    long insertedTrack = sqlite3_last_insert_rowid(db.dataBase);
    sqlite3_exec(db.dataBase, "COMMIT", 0, 0, 0); //End transaction

    return insertedTrack;
}
}
@catch(NSException *exception) {
    //Log the exception and ROLLBACK!
}
@finally {
    sqlite3_clear_bindings(addTrackStatement);
    sqlite3_reset(addTrackStatement);
    sqlite3_finalize(addTrackStatement); 
}
}

So again my question: Should I use a return value to indicate that something had gone wrong with either the preparing or executing of the sql statement? Should I use NSError or use Exception like I am right now?

Tikkes
  • 4,599
  • 4
  • 36
  • 62
  • Of course, if this is a project for a class, and you were told to use exceptions, there's no great harm in doing so. It would be a good exercise in using exceptions, since it's not terribly complex. – Hot Licks May 15 '12 at 15:50

2 Answers2

2

The exception implementation on iOS is pretty crummy and inefficient. But since errors are (presumably) rare, and SQL operations are not speedy fast anyway, it probably doesn't matter much (in terms of performance) which you use, so long as you don't use exceptions for the "entry not found" and "no more data" cases.

Exceptions can be handy where there are a lot of operations in sequence, since you don't have to individually deal with error handling and clean up after each one. However, in the above case (where you still have to test for error after each op) the benefits are not that great.

There is a "poor man's exception" scheme that can be used in such cases:

errorCode = NoError;

do {
    rcode = operation1();
    if (rcode) { 
        errorCode = ErrorA;
        break;
    }        
    rcode = operation2();
    if (rcode) { 
        errorCode = ErrorB;
        break;
    }        
    rcode = operation3();
    if (rcode) { 
        errorCode = ErrorC;
        break;
    }
    <More stuff>
} until(FALSE);

if (errorCode == NoError) {
    <do normal path stuff>
}
else {
    <do error path stuff>
}

This is reasonably efficient on all platforms that I know of, and is readily translated into most other programming languages, even those lacking exceptions.

Hot Licks
  • 47,103
  • 17
  • 93
  • 151
1

I would suggest using NSError in this case, since the errors are such that you can recover from if you know the reason, so you can post error codes and recover from them. NSExceptions are to be used when you don't know how to recover from them and want them for your release. Read More about errors vs exceptions here. You can get the list of sqlite error codes and messages here. Based on them you can handle them in your code.

Community
  • 1
  • 1
zahreelay
  • 1,742
  • 12
  • 18