views:

204

answers:

11

I've gotten in the habit of using a general catch statement and I handle those exceptions in a general manner. Is this bad practice? If so, how do I know which specific exceptions could be thrown and which ones do I catch?

+2  A: 

The methods you run will generally show what exceptions can be thrown. You can then catch accordingly.

If it's your own code, you can generally see what will be thrown, or use the underlying classes exceptions as a guide on what you will need to catch.

I recommend a few links:

Kyle Rozendo
I believe the question is asking how to find out what the underlying classes are going to throw? e.g. Java has a `throws` clause, which documents this. .NET does not.
spoulson
@spoul - Move your mouse over the class or method you're using, and it shows. Or use object explorer.
Kyle Rozendo
@Kyle, IMHO that is not a reliable way to figure it out. I mean, when using EF and generated POCO objects, none of this is documented. Using Linq muddies the waters even more. What about when I use DI and IoC containers? Whoa, a LOT of stuff to consider and hardly a drop in the bucket is documented in the way you suggest!
Jaxidian
"Catch accordingly" is a pretty broad statement... I would suggest that you catch and handle only those exceptions that you know how to handle correctly. E.g., I have a task that makes database calls. In that task I handle SQL and network exceptions thrown from those calls because I know I can recover from them properly. I don't catch anything else in that context because there's really no way for me to recover from them. ("Recover from them properly" in this case means I'm not corrupting application state or other resources.)
Curt Nichols
A: 

When using framework methods, you can check the MSDN documentation. Each method description has a list of potentially thrown exceptions.

As an example, check the Exceptions paragraph on File.Open() documentation.

When using your own method, you should be aware of exceptions potentially thrown by your methods.

Thibault Falise
Or in Visual Studio, just hover over the method and read the doc comment, also lists the thrown exception types.
Matt Greer
+8  A: 
  1. Yes, except in a couple of very specific cases that's bad practice. The one common case I can think of where catching all exceptions isn't a lousy idea is when you're logging a message or a stack trace just before the app is about to tear itself down (or, maybe, you're logging and rethrowing).

  2. Catch only the exceptions you know you can handle. No more, no less. If you don't know an exception can be thrown from a method, you aren't going to handle it properly anyway so don't catch it. Methods and libraries are responsible for documenting exceptions that you should be able to handle. Also, don't catch exceptions that indicate a logic failure, such as NullReferenceException and ArgumentException. These indicate a genuine bug in your software that you should fix, not something that you should handle at runtime.

Greg D
IMHO Logic Bugs should be caught, too. It's better to Fail and Log than to explode into a users/customers face. Those bugs should not appear of course, but they always do and customers don't care what kind of problem caused the crash, they just remember that you delivered crashing software. I agree with most of what you said though.
dbemerlin
@dbemerlin: Customers hate software that doesn't function properly and they don't know why. You should always shutdown your application in the face of unhandled exceptions.
Jeff Yates
@dbemerlin - I do agree with you from the standpoint of "customers see a bug and that is bad." However, if testing has done their job, they should find many/most of those logic bugs and you can properly handle the errors (such as checking to make sure an object isn't null, or to validate inputs before handling a form, etc).
JasCav
I'm with Jeff Yates on this one, 110%. With (maybe?) the exception of reflection-heavy code, I consider any runtime catches of logic-based exceptions to be a code smell. You can and should log it, of course, but tear the application down.
Greg D
+1  A: 

The bigger question is if you need to do specific error handling on specific exceptions. If you just need to catch any errors that occur, there is nothing wrong with just making a generic try/catch block:

try
{
    // Some Code
}
catch
{
}

However, if you need do specific handling on certain exceptions, you can specify multiple catch blocks per a single try:

try
{
    // Some Code
}
catch(ArgumentException argE)
{
}
catch(NullReferenceException nullE)
{
}
catch(Exception e)
{
    // Everything else
}

If you can't recover from an exception, don't catch it at that level.

Tejs
+3  A: 

Yes, that is bad practice. Rule of thumb: "catch the exceptions you are in a position to respond to, let the other ones go."

try {
    File.Open(usersChosenFile, FileMode.Open);
} catch(FileNotFoundException) {
    // tell the user the file is gone, give them a chance to respond
    // this is good
} catch(UnauthorizedAccessException) {
    // this is good too
} catch(Exception) {
    // what did you just catch? Who knows. What if its OutOfMemoryException?
    // Do you really want to deal with that here? Let this one go by
}
Matt Greer
+1  A: 

IMO - don't catch any exception unless you plan to add value to it and/or it can be handled in that method only.

Please do have a common exception handler which handles all un-handled exceptions.

HTH.

Sunny
A: 

As Kyle said, make your methods small in length, put try/catch around small areas only. Hover the mouse over the methods that you call - you should get a list of exceptions then. This will not catch every exception listed, but Exceptions can also be discovered empirically if you print the exception type inside of your catch (Exception e) { ... }. What you are after is e.GetType().FullName and e.StackTrace and e.Message and e.InnerException ... or a subset of what I listed.

Hamish Grubijan
A: 

Documentation will often describe what exceptions a method might throw and the conditions under which that might happen. This is especially the case with Microsoft's reference documentation for the .NET framework.

In my view, exceptions should only be caught if you have a good reason to catch them. This usually means that catching and handling them in a generic manner is unnecessary. Logging exceptions (a very common activity in an exception handler) should only happen at the bottom of the call stack or whenever you don't rethrow the (possibly wrapped) exception , which should be rare. If you have some action you want to take place at every frame in the call stack when an exception is bubbling down, take a look at Aspect Oriented Programming (AOP) techniques.

Daniel Renshaw
+1  A: 

Except in rare situations, I generally think of catch blocks as a code smell.

Prevent exceptions being thrown at all by checking for conditions beforehand. For example, if reading from a file, use classes in System.IO to check if the file exists, rather than using a catch block to handle the situation where the file doesn't exist.

Catch blocks should not form part of your application logic.

David
A: 

You should catch those exceptions for which you can develop a reasonable strategy to deal with the problem. There's no point in catching an exception if there's no reasonable alternative (trying again later, using a different technology/technique to achieve the same overall goal, informing the user that the goal cannot currently be achieved and what they can do to remedy the situation).

Exception (pardon): It is worth having something at the very top level (e.g. Application.ThreadException or AppDOmain.UnhandledException) to attempt to log those exceptions that you haven't handled. If logging fails, you're doomed anyway.

But blindly swallowing all exceptions (especially at a low level) can lead to very frustrating debugging/diagnostic sessions.

Damien_The_Unbeliever
A: 

You must make a design decision as to whether you really need to catch all exceptions at that point in code. I know of two conditions where catching Exception makes sense:

  • If you absolutely cannot allow an exception to bubble up and terminate your application.
  • The calling code expect an exception to be thrown by your method/property because it is an atomic transaction. In which case, you catch all exceptions and return safely.

The downside of catching all exceptions is masking a potentially useful error message and disregarding it, causing unexpected side effects in your application.

spoulson