Should I throw a KeyNotFoundException for a database lookup?

1.9k views Asked by At

I've got some code that, given an ID, returns an item from the database. If no item matches the given ID, is it appropriate to throw a KeyNotFoundException, or are such exceptions meant only for Dictionary types?

3

There are 3 answers

3
Heath On BEST ANSWER

Depending on the framework you're using to access the database (ODBC, ADO.NET, etc.) there's likely a better alternative that the framework would throw.

The System.Data namespace contains several such exceptions as examples: http://msdn.microsoft.com/library/system.data.

Really, though, as long as you document what exception you're throwing and in what conditions it doesn't matter too much. Using something common is best because people may assume, but if they are reading documentation they will handle whatever exception you say would be thrown.

0
rossipedia On

The MSDN page for KeyNotFoundException states:

The exception that is thrown when the key specified for accessing an element in a collection does not match any key in the collection.

Semantically a KeyNotFoundException would be appropriate. Just make sure your error message is descriptive enough to actually help when debugging. Also, remember that you lose any contextual type information that using a custom exception type would give you.

A custom exception type gives you the ability to differentiate between the two conditions using general C# idioms, like so:

try 
{
  // do some database stuff
} 
catch(KeyNotFoundException e) 
{
  // Here you know that it was more than likely caused by a Dictionary 
  // or some such collection
}
catch(DatabaseKeyNotFoundException e)
{
  // Here you know that it was caused by a DB record not being found
}

Whichever you choose, just make sure you think about it, that it's consistent and logical. Don't just choose one because it's easier.

0
AWinkle On

MSDN says yes* (if you consider a database table a collection) -

The exception that is thrown when the key specified for accessing an element in a collection does not match any key in the collection.

Why not just return false or some other indication that the value was not in the database?