George F DArcy

For sometime now I've been bothered by something - the question "am I handling all of the exceptions that I should be ".

How does one know which exceptions can occur from a particular block of code

Is there a list of all possible exceptions (excluding custom ones)

And is there a simple way to know which exceptions catch, ie will visual studio or any 3rd party apps (ie refactor) tell me

thanks

George



Re: Visual C# General Possible exceptions

Steve Py

The only way I know what exceptions blocks of code will raise is to check the documentation for the functions contained in the code being run. MSDN docs will outline generally all exceptions that their methods raise, though third party libraries may not be as thorough.

In general it usually helps to handle specific errors only when you have specific behaviour to take with those exceptions (I.e. retries, etc.) If all your exception handling is the same, just catch on Exception.

In cases where I'm dealing with active users (WinForms apps) I'll EventLog or Log-File entry any exception at the lowest level that I can catch it, then let it "bubble" as a user-presentable message back to the UI process that either triggered it or can prompt the user. In services, and non-UI elements I just event-log/Log-File then bubble up a exception that the service can decide whether to terminate, or continue. (With or without a sleep before retry)






Re: Visual C# General Possible exceptions

Peter Ritchie

In short, there's no way to know. Ideally the documentation for the method(s) in question detail all the possible exceptions that it/they may throw. But, that assumes they know about all the exceptions that may be thrown by all the exceptions that they use and don't handle.

For me, the first step is to go by the documentation. As I develop the solution this may reveal other exceptions that aren't documented (ArgumentNullException or NullReferencExceptions are common ones). Testing all the possible scenarios is the next step, this will often reveal other exceptions that aren't documented.

Keep in mind, you don't need (and don't want to) handle all possible exceptions. Exception handling is hierarchical; some exceptions may be handled more effectively at different levels of the hierarchy, handling all exceptions at a particular level almost always leads to problems.






Re: Visual C# General Possible exceptions

micvos

If your method can give all kind of exceptions by different calls to other methods, create your own exception so you know it was your own method where it went wrong and attach the original exception as an inner exception. It's very useful for solving the problem later on. Don't try the solve every possible error. Just not possible.






Re: Visual C# General Possible exceptions

George F DArcy

thank you all, very helpful stuff.

Just a few more questions, please;

"If all your exception handling is the same, just catch on Exception."

I thought catching on Exception was the Golden No-No

"Keep in mind, you don't need (and don't want to) handle all possible exceptions. Exception handling is hierarchical; some exceptions may be handled more effectively at different levels of the hierarchy, handling all exceptions at a particular level almost always leads to problems."

Yeah, I figured as much. Good tip.

"If your method can give all kind of exceptions by different calls to other methods, create your own exception so you know it was your own method where it went wrong and attach the original exception as an inner exception."

I basically understand what you're getting at. Could you possibly expand on it a bit With this practice couldn't we catch ALL exceptions, package them up, and re-throw (allowing it to bubble up and be handled/not handled later on)





Re: Visual C# General Possible exceptions

Peter Ritchie

I don't recommend throwing Exception and I don't recommend catching Exception. You can create you own universal exception class if you want and throw/catch that for all your exceptions (don't derive from ApplicationException); but don't use Exception.

micvos' "If your method can give all kind of exceptions by different calls to other methods, create your own exception so you know it was your own method where it went wrong and attach the original exception as an inner exception." is basically saying wrap the exceptions that can be thrown by the methods you use, where appropriate. In the case of really general exceptions like SqlException or CryptographicException (see http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=2125926&SiteID=1#2125926 where I show an example of catching this general exception and wrapping it in another) this can add context that cannot be retrieved from higher levels because the exception is so general. In the other thread, for example, a CryptographicException is thrown, but you can only tell that the exception is due to a bad key/IV pair if you catch it on the call to Encrypt. If you don't know it was thrown from a call to Encrypt (i.e. it was caught at a higher level) you may not have enough information to handle it effectively.




Re: Visual C# General Possible exceptions

Steve Py

About catching "Exception". The golden rule as far as I've observed is you should never catch exceptions you aren't prepared to handle. Throwing Exception is taboo, it's just a lazy exception where you should either throw a more specific exception. (Usually a user-defined type.) Catching Exception however isn't a problem provided you're prepared to handle any exception that comes up at that level, hence if the exception handling you want to perform "is the same" for caught exception types, just catch Exception. Personally I either handle exceptions (logging) at key levels and bubble a custom exception up, or let exceptions bubble up to the nearest key level.

An example of a key level would be in the "Save()" method of a Business object like "Customer". This method is going to interact with any number of blocks of code that may throw exceptions. This code might include encryption, validation, or specific data provider errors. (Connectivity, constraints, etc.) In some cases such as in a data layer I would catch on constraint violations for example and bubble an informative custom exception with information about what field was duplicated/invalid. This exception would also get output to Trace. Any other exception would be bubbled "raw". However, when an exception gets back up to "Save()", I will catch my custom exceptions and raise a custom "SaveException" indicating why my Customer cannot be saved, and catch on Exception to raise a SaveException after outputing the exception to Trace. The SaveException's role is to bubble back up to the UI that started the call and present the user with a meaningful message and/or govern what action the system will take. (I.e. write to a local cache, retry, etc.) I don't opt to have Save try and catch specific error types because Save doesn't know if it's talking to a ADO.Net wrapper, Web Service, Remoting client wrapper, etc. In the end, Save's responsibility is to save the customer or report back "The customer cannot be saved."

So as far as the golden rule of catching on Exception, I believe it should be interpreted not that you should *never* read "catch( Exception ex)" in your code, but rather you should be wary of situations where it's unintentionally eating exceptions without properly handling or re-raising them.

Things to watch out for:
catch()
catch (Exception) without throw
catch(Exception ex) without throw
or unused "ex" references detected by tools like Resharper in catch( Exception ex )

Of course, like just about anything in software development there will be differing opinions, best, worst, it's everyone's decision to make for themselves...

The road to Heck is paved in best practices.