Alex Rivera | Logout

.NET and C# Exceptions. What is it reasonable to catch

Asked 2009-08-19T07:23:21.607
12

Disclaimer, I'm from a Java background. I don't do much C#. There's a great deal of transfer between the two worlds, but of course there are differences and one is in the way Exceptions tend to be thought about.

I recently answered a C# question suggesting that under some circstances it's reasonable to do this:

 try {
   some work
 } catch (Exeption e) {
       commonExceptionHandler();
 }

(The reasons why are immaterial). I got a response that I don't quite understand:

until .NET 4.0, it's very bad to catch Exception. It means you catch various low-level fatal errors and so disguise bugs. It also means that in the event of some kind of corruption that triggers such an exception, any open finally blocks on the stack will be executed, so even if the callExceptionReporter fuunction tries to log and quit, it may not even get to that point (the finally blocks may throw again, or cause more corruption, or delete something important from the disk or database).

May I'm more confused than I realise, but I don't agree with some of that. Please would other folks comment.

  1. I understand that there are many low level Exceptions we don't want to swallow. My commonExceptionHandler() function could reasonably rethrow those. This seems consistent with this answer to a related question. Which does say "Depending on your context it can be acceptable to use catch(...), providing the exception is re-thrown." So I conclude using catch (Exception ) is not always evil, silently swallowing certain exceptions is.

  2. The phrase "Until .NET 4 it is very bad to Catch Exception" What changes in .NET 4? IS this a reference to AggregateException, which may give us some new things to do with exceptions we catch, but I don't think ch

Edit
Report

1 Answer

9

As a general rule you shouldn't catch exceptions unless:

  1. You have a specific exception that you can handle and do something about. However in this case you should always check whether you shouldn't be trying to account for and avoid the exception in the first place.

  2. You are at the top level of an application (for instance the UI) and do not want the default behaviour to be presented to the user. For instance you might want an error dialog with a "please send us your logs" style message.

  3. You re-throw the exception after dealing with it somehow, for instance if you roll back a DB transaction.

Your finally blocks always execute. Your code sample is correct - the low level method should just have try and finally. For instance an unmanaged call might know that it needs to dispose of the unmanaged resource, but this wouldn't be exposed to .Net methods calling it. That call should get rid of the unmanaged resource in its finally block, and calling managed methods can handle exceptions or just pass them on up.

If there's something in an exception that you need to handle you should re-throw the exception, for instance:

try {
    conn.BeginTransaction();
    //do stuff
    conn.CommitTransaction();
}
catch (Exception) {
    conn.RollbackTransaction(); //required action on any exception
    throw; //re-throw, don't wrap a new ex to keep the stack trace
}
finally {
    conn.Dispose(); //always dispose of the resource
}
answered 2009-08-19T07:41:09.403

Your Answer