Exception Catching: All or Specifics?

joe_pool_is

Contributor
Joined
Jan 18, 2004
Messages
507
Location
Longview, TX [USA]
The more I learn about exceptions, the more I feel like I should *not* be catching and dismissing general exceptions in my code like I do:
Code:
try {
  DoThis1();
} catch (Exception err) {
  LogError(err);
}
So, what I've been trying to do is catch the exceptions that could be thrown by particular routines, but I don't know which ones need to be caught and which ones are obvious checks that don't need catching.

Take the ArgumentNullException. If I do a simple check on my object,
Code:
if (obj != null) {
  DoThis2();
}
can I eliminate the ArgumentNullException?

For sending a simple email, I find myself catching about 5 exceptions:
Code:
try {
  SmtpClient client = new SmtpClient(strIpAddress);
  client.Send(email);
} catch (SmtpFailedRecipientsException) {
  // handle it
} catch (ArgumentNullException) {
  // handle it
} catch (SmtpException) {
  // handle it
} catch (InvalidOperationException) {
  // handle it
} catch (ArgumentOutOfRangeException) {
  // handle it
} catch (ObjectDisposedException) {
  // handle it
}
Is this ridiculous or is it just me?

So I go to build my application, and VS2005 throws up and error:
A previous catch clause already catches all exceptions of this or of a super type ('System.InvalidOperationException')
Where is the documentation on what order to catch my exceptions in? I found documentation on Exceptions on MSDN, but nothing telling me what order they can be called in.

Sometimes I just want to go back to catching the general exceptions, but I also want good code.
 
As a rule if you have a different recovery / error strategy for each of those exception types then the separate catch blocks make sense. If you are doing the same thing for any of those then it may make sense to have a more general handler for those cases (e.g. ArgumentNullException and ArgumentOutOfRangeException both inherit from ArgumentException and could be caught through their base class).

Unless you are doing things involving multiple threads then a valid object shouldn't become suddenly null (unless the documentation states otherwise e.g. WeakReferences) so doing the initial check would normally be fine.

Regarding the order to check - it is simply the inheritance hierarchy that dictates the order the more general exceptions are ones that are inherited from.
 
While I have your ear, I've got a related question:

There are times that I write a block of code in a try/catch routine, and when I run the application, I still get thrown out at the program's entry point with an unhandled exception.

What causes those?

How do I prevent those?
 
Back
Top