I recently attended the “Debugging .NET Applications” course by Jhon Robbins. In contrast to my expectations, the course was not at all like his books. I was a great fan of his books but really got disappointed with the course. He is a really nice person, he will crack nice jokes, make you laugh, but in the end, the course was not delivering what you expect. His demos were not working, the topics were simply overview and he was not talking the class with him.
Some of you might totally disagree with me and I can understand. He is a great author.
Inspite of all the disappointment, I did find some topics useful and one of them was .NET Exceptions. There were some good points which are listed below.
The idea of exception handling is to give a single place for all the clean up in case of unexpected conditions. .NET exceptions are totally different from C/C++ exception where there was no base class for exception but in .NET. all the exceptions were derived from System.Exception class.
Here are some do's and dont's for .NET excptions.
- Never ever throw or catch System.Exception. - The idea is, you should catch what you are throwing, or you should catch if you are calling some function which is throwing an exception because of your wrong input. You should never catch any exception which is coming because of some other reason, like low memory condition etc.
- Never throw these exceptions - System.Exception (already covered), System.ApplicationException, System.SystemException, System.NullReferenceException, System.IndexOutOfRangeException. All these exceptions can also be thrown from CLR so there would be now way if you throw any of the above exception and catch, weather the exception was yours or not. Always throw a more specific exception rather than a generic one.
- Never throw the exception you caugth by calling throw exp (where exp is the exception you caught). This will loose the stack trace. Rather, either call throw, which will rethrow the caught exception with proper stack trace, or create a new exception by setting the innerexception to the exception you just caught. This way, the caller will know the exact stack where the original exception was caused.
- Always drive your exception from System.Exception, not from System.ApplicationException. (This is supposed to be from latest Design Guidelines)
- Drive a new exception only if necessary. If its a generic exception type, throw the existing defined exception. for ex - System.ArgumentNullException.
- When driving your own exception, make sure you provide at least these 3 constructors. 1. parameterless (default) constructor. 2. A single string parameter to set the message. 3. A string and an instance of an exception derived type, so that you can pass the inner exception in the constructor.
In addition to this, exception should be thrown only when there was a voilation of contract between the caller and callee. Is should not be used as a way of communicating results. Remember, exceptions means unexpected conditions where the execution cann't be continued.
I found these points useful and thought some of you might find them useful as well. Let me know if you have some more generic guidelines which can be used while writing code.
-Ashish