Exceptions can be defined as a deviation from the expected flow of a program caused by logical, I/O or environmental issues. So the concept of structured exception handling enables programmers to identify and safeguard themselves from those potential code regions that might get subjected to any of these factors. In some cases, when an exception occurs, it may be advisable to terminate a whole process and in some other cases it might be needed to branch out the execution path to a different route without completely terminating it.
Main Building Blocks (Try .. Catch .. Finally)
The code block that can cause exception to occur is placed inside a ‘try’ block; potential exceptions are placed in single or multiple ‘catch’ block(s) and an optional ‘finally’ block is needed in case if we need to do any sort of garbage collection or cleaning activity. It is to be noted that a finally block always get executed irrespective of any catch block execution. A very basic try catch block is shown in the figure below.
In this example; we are reading the content of a file into a text box control. So the point of concern here is the opening of the file as a FileStream object and reading the content using StreamReader object. That’s why this entire operation has been put into the try block. And we have specified multiple catch blocks that can be thrown during the operation.
Use of Throw
Throw statement is used to denote a case where we want to send the control to the calling function from where current execution got initiated. So if throw statement is used in a function then one of the calling function in the stack chain must have proper catch block to cater to this potential exception.
What to Catch
Any exception class (inheriting from the base class System.Exception) provides us mainly the following details when an exception occurs:
- Message property: this contains the description of the exception occurred;
- StackTrace property: this contains the full details about the exception occurred starting from the origination in the stack. For example; if a construct contains multiple level of throw statements and in the UI layer the exception is caught; then using this property is useful since it will traverse to the originating source for the exception and will give the full details.
In professional programming; it is expected to log all the exceptions either in a log file or in a database table so that we can
- analyze the errors occurring intermittently in a production environment;
- correctly predict the date / time when a specific exception occurred;
- if any unauthorized user tries to perform a restricted activity the administration department can be alerted.
In the below image two cases has been shown to record the exception logs in a log file in two different functions i.e. LogException (logs from the Message property of the exception class) and LogExceptionDetails (logs from the StackTrace property of the exception class). So in a development environment the latter is a good log level to maintain as more details will be available to the development team whereas the former is clearly a better option in a production environment.
Nested Exception Handling
Nested exception handling can be implemented if multiple level of exception handling has to be taken care of. In this cases; if any exception occurs in the inner try blocks it will not hamper the execution of the outer try block any way and seamless processing can happen in the outer block. In Picture 5; an example of nested exception handling has been shown. In the outer try block only UnauthorizedException has been handled but in inner try block where individual files are accessed to gather statistics IOException has been considered as a potential exception.
Throwing Custom Exceptions
Often it becomes necessary to add custom Exception classes in order to implement business logic. In those cases it is possible to write a user-defined exception class inheriting from System.Exception class. In the figure below; the declaration and usage of a user defined exception class has been shown. In this example the objective of the custom exception class is to notify the user that a valid file has not been selected. So the Message property has been overridden accordingly with a specific message. After this when this exception condition occurs; system returns the overridden message to the calling method.
See below image: Invoking of the above user-defined exception class
One important guideline that Microsoft FxCop (static code analysis tool) tells about exception handling is Do Not catch general exception types. Although this is not mandatory to obey this rule always but it is good to follow this because of the following reasons:
1. Sometimes it is needed to treat different exceptions in different ways;
2. It is always a good practice to catch the exceptions at the granular level with more unit test coverage;
3. If in some cases it becomes impossible to follow this rule; then in the last catch block the general exception can be thrown to avoid having unhandled exception.
Feel free to share the article.