I am trying to come up with an exception handling strategy for my Android application (although this may also apply to any Java app). For example, I am looking at the delete() ContentProvider function in the example Notepad application:
public int delete(Uri uri, String where, String[] whereArgs) {
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
int count;
switch (sUriMatcher.match(uri)) {
case NOTES:
count = db.delete(NOTES_TABLE_NAME, where, whereArgs);
break;
case NOTE_ID:
String noteId = uri.getPathSegments().get(1);
count = db.delete(NOTES_TABLE_NAME, NoteColumns._ID + "=" + noteId
+ (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
What happens if the Uri
is null? or getContext
()? or getContentresolver
()?
I have come to the conclusion that the ContentResolver
is not the place to catch the exceptions, but it should re-throw them or throw new exceptions so the app can display a meaningful error message.
Would the following or something similar be a bad approach (overkill) - should I just let NullPointerException
s, etc. bubble up to the top to be handled in a more generic way (as per the example)?.
public int delete(Uri uri, String where, String[] whereArgs)
throws SQLiteException, IllegalArgumentException, NotifyException {
if (null != mOpenHelper) {
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
if (null != db) {
if (null != uri) {
int count = 0;
switch (sUriMatcher.match(uri)) {
case NOTES:
count = db.delete(NOTES_TABLE_NAME, where, whereArgs);
break;
case NOTE_ID:
String noteId = uri.getPathSegments().get(1);
count = db.delete(NOTES_TABLE_NAME, NoteColumns._ID + "=" + noteId
+ (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
if (null != getContext()) && (null != getContentResolver()) {
getContext().getContentResolver().notifyChange(uri, null);
} else {
throw NotifyException("Failed to notify change");
}
return count;
} else {
throw new IllegalArgumentException("Must provide URI");
}
} else {
throw new SQLiteException("Failed to get database");
}
} else {
throw new SQLiteException("Invalid database helper");
}
}
Disclaimer: this code may not compile! it is an example.
It certainly is harder to read! I don't know what the right balance is and need some help!.
Update: I read through Android's recommended practices (see http://source.android.com/source/code-style.html#java-language-rules) but it just confused me further!