Over on channel9 I saw one of my pet hates, a try {} catch (System.Exception) {} block and responded with the refrain that people I've worked with (Hi Simon!) will have heard, "Don't catch System.Exception". Ok, I'm exaggerating for effect, but a single try {} catch {} statement is generally bad. Catches should be granular, you catch what you can react to and what you can "fix". For example, if you're trying some file operations I would expect to see
try
{
}
catch (FileNotFoundException ex)
{
}
You should know the exceptions each statement you make might raise, the MSDN documentation lists those that come from the framework and your own comments should list those which come from your own code. With granular exception handling you can react appropriately, in the example above you could prompt the user for a file that exists and then try again. By simply catching System.Exception you have no real idea what the problem is. Worse still is rethrowing System.Exception;
try
{
}
catch (Exception ex)
{
throw(ex);
}
Here you've added nothing. You're not dealing with the exception (you can't, you don't know any specifics). I would only expect to see a rethrow of System.Exception in two circumstances, where you are logging errors within your method or where you wrap the exception in a custom exception (based on the Eric Gunnerson's Well-Tempered Exception) which includes specific information garnered from your object, for example
public Survey getSurveyFromID(string surveyID)
{
try
{
}
catch (SqlException ex)
{
throw new SurveyNotFoundException("Survey not found", surveyID, ex);
}
}
Here we are creating a custom exception, with a custom property of the surveyID and wrapping it around the original SqlException.
When should we create custom exceptions? My feeling is that custom exceptions should be created for situations you can react to. If you don't care about knowing the surveyID in the previous example then let the SqlException bubble upwards.
Catching System.Exception should be be the last resort. Catching a System.Exception and performing an action other than logging and quitting is most likely guesswork on your part as to what the error is. At best you're masking errors, at worse you're catching an out of memory exception or a disk corruption message and making things worse by continuing. Catch what you can handle. Let the rest bubble upwards unless you can "add value" to the exception by providing more information in a custom exception and never, ever, catch system.exception and do nothing except as part of your single, per application unhandled exception handler.