sqllite and Cocoa represent two distinct worlds with different error handling idioms. In order to bridge that semantic gap in my code, I came up with the following helper code:
Usage in the code would be (“select” is “aselect” on purpose):
Unit test to see what it would return in case of a simulated error:
Where mine SchemaUpdater is just a simple class with snippet shown above having error in sql statement and calling that handleSqlError method.
The output of NSLog is:
This is it for a moment. You might be also interested in a follow up post: Check if sqllite table exists
...
Or wait! Here are some links that enlightened me on NSError idioms:
http://weblog.bignerdranch.com/?p=360 (definitely take a look if your way of checking for error is error!=nil)
http://www.cimgf.com/2008/04/04/cocoa-tutorial-using-nserror-to-great-effect/ (probably the most comprehensive one)
Stackoverflow nn risk of the NULL dereference
Official:
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSError_Class/Reference/Reference.html
Using and Creating Erorr objects
@implementation DbHelper
+ (void)handleSqlError:(sqlite3 *)db error:(NSError **)error
{
NSLog(@"Error while executing sql statement. '%s'", sqlite3_errmsg(db));
NSError *underlyingError = [[[NSError alloc] initWithDomain:@"db"
code:sqlite3_errcode(db) userInfo:nil]autorelease];
// Make and return custom domain error.
NSArray *objArray = [NSArray arrayWithObjects:[NSString stringWithFormat:@"sqlite error:%s", sqlite3_errmsg(db)], underlyingError, nil];
NSArray *keyArray = [NSArray arrayWithObjects:NSLocalizedDescriptionKey,
NSUnderlyingErrorKey, nil];
NSDictionary *eDict = [NSDictionary dictionaryWithObjects:objArray
forKeys:keyArray];
*error = [[[NSError alloc] initWithDomain:@""
code:1 userInfo:eDict] autorelease];
}
...
sqlite3_stmt *checkStmt;
const char *sql = "aselect count(*) from sqlite_master where type='table' AND name=?";
...
if(sqlite3_prepare_v2(db, sql, -1, &checkStmt, NULL) == SQLITE_OK)
{
...
}
else
{
[DbHelper handleSqlError:db error:error];
sqlite3_finalize(checkStmt);
sqlite3_close(db);
return false;
}
- (void) test_when_invalidstatement_should_return_error
{
NSError *error = nil;
bool exists = [SchemaUpdater tableExistsWithName:@"note" error:&error];
STAssertFalse(exists, @"When statement is invalid, exists should be false!");
STAssertNotNil(error, @"For this test case error should not be nil!");
NSLog(@"%@", error);
}
The output of NSLog is:
Error Domain= Code=1
"sqlite error:near "aselect": syntax error"
UserInfo=0xbd28b60
{NSUnderlyingError=0xbd28b40 "The operation couldn’t be completed. ( error 1.)",
NSLocalizedDescription=sqlite error:near "aselect": syntax error}
...
Or wait! Here are some links that enlightened me on NSError idioms:
http://weblog.bignerdranch.com/?p=360 (definitely take a look if your way of checking for error is error!=nil)
http://www.cimgf.com/2008/04/04/cocoa-tutorial-using-nserror-to-great-effect/ (probably the most comprehensive one)
Stackoverflow nn risk of the NULL dereference
Official:
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSError_Class/Reference/Reference.html
Using and Creating Erorr objects
No comments:
Post a Comment