1. Introduction to Exceptions

An Exception is an object delivered by the Exception class. This Exception class is exposed by the System.Exception namespace. Exceptions are used to avoid system failure in an unexpected manner. Exception handles the failure situation that may arise. All the exceptions in the .NET Framework are derived from the System.Exception class.

To understand exception, we need to know two basic things:

Somebody sees a failure situation that happened and throws an exception by packing the valid information.

Somebody who knows that a failure may happen catches the exception thrown. We call it Exception Handler.

Below is a simple example, which shows what happens when an Exception is not handled:

In the above code, look at the function F1 that throws an Exception. But, there is no handler to deal with the thrown exception. This situation is called an Un-Handled exception situation. When you execute the code, you get an unhandled exception dialog.

The above dialog is shown in debug mode, so you may get a chance to break the execution to see where the exception is thrown (or) continue ignoring the exception (not advisable).

In release mode, you will get un-handled Exception in the form of Application crash.

So, how do we avoid Un-Handled Exception? Simple, handle it.

2. Handling Exception

To handle the exception, we need to place the code within the try block. When an exception occurs inside the try block, the control looks for the catch block and raises an exception that is handled in the catch block. Below is the simple skeleton for the try and catch block:

The above skeleton handles any exception. But, the main disadvantage is that we don’t know what exception is raised and who raised the exception. Below is the example that handles the Exception raised by the function F1 and avoids the crash:

3. Exception Bubbling

In the above example, we saw that Exception is handled in the catch block. But, the function call order is simple (Call Stack) that is; StartProgram calls the function F1 and F1 raised exception is handled in the catch block of the StartProgram.

Imagine the situation what happens if there are multiple nested function calls, and exception occurred in the fourth or fifth nested call. Look at the picture below:

F1(): Calls F2 within the try block and handles the exception in catch block

F2(): Makes a call to the function F3. But it neither wraps the call for F3 in the try block nor has the exception handler

F3(): Raises an Exception

Note, when the exception is thrown by the function F3, even though the caller is F2, as there is no catch handler, the execution comes out of F2 and enters the catch block of F1. Travelling back from F3->F2->F1 is known as Stack Unwind. And exception occurred in F3 is handled in F1 even when there is no handler at F2 is known as Exception Bubbling.Below is the example that demonstrates the Exception Bubbling:

4. The Importance of Finally Block

In the above example, we saw that when an exception occurs, we directly jump back on the call stack and travel back searching for the catch handler. What about the piece of code that comes next to the exception raising code? If we do releasing resource and releasing the heap memory in the next couple of statements, that will not get reached. Right?

Finally block is the solution for this. Now look at the improved exception-handling skeleton below:

try
{
}
catch
{
}
finally
{
}

Whatever happens inside the try block, it is guaranteed that finally block gets executed. Hence, all resource releases should be in the finally block. Have a look at the below picture:

Exception raised at function F3 is handled in the function F2. Look at the try block, I marked two blocks of code before exception and code after exception. It is obvious that when an exception raised, the set of code inside the code after exception is never executed. If resources are allocated in code before exception and the allocated resources are released in code after exception, we do have a resource leak for each exception occurred. Also, think about business logic that needs to revert back apart from the resource leak. This is why finally block is introduced.

Whether an Exception occurs or not, the code inside finally block always gets executed. So you can keep all the cleaning code inside the finally block. The attached sample solution explains the above situation. Put a break point in the very first statement of the function public void StartProgram() and examine the situation explained above. Note, the usage of try block with only finally and without catch in function F2. Think about it.

5. What is Exception Class?

This class is provided by .NET Framework to handle any exception that occurred. The Exception class is the base class for all other Exception class provided by .NET Framework.

The exception object has some important properties. Some of then are given below:

Property

Usage

Message

Gives detailed information about the message

StackTrace

Gives the function stack to show where exception is thrown

Targetsite

Shows which method throws the exception

In the previous example, we only used the catch block and missed all the above said information. The exception object is thrown by the piece of code, which raises an Exception and the handler code catches that Exception object and makes use of the information packed in it. Consider the below example:

The example was shown just to understand from where the object that is used in the catch block is coming from. Hope, now you know the exception instance created on the throw statement caught in the catch block and used. Note that, the base class of DivideByZeroException is ArithmaticException, which is derived from the System.Exception. Now the question is, May I use ArithmaticException in the catch block? Yes. Why not? That is the beauty of polymorphism. When you do, always keep in mind that you are moving from more specialized information thrown to the generalized one.

6. Handler for Multiple Exceptions

A code placed in the try block can raise different kinds of exception. It can be say, a Divide by Zero or a Network System Access Denied or a File not exists. How do you handle all the exceptions? The answer is, you can place multiple catch blocks for a try block. When an exception is thrown, type of that exception is examined against each catch block. When a match occurs (even polymorph), the exception enters into the catch block and gets handled.

Let me walk through an example, which will explain the following to you:

Make use of Exception object in the catch block

Using multiple catch blocks for different exceptions

The importance order of the catch blocks

1) Program enters the main function and calls the member function StartProgram after creating the object of type ExceptionsP2.

2) The StartProgram function makes a call to Calculate function. And this call is placed in the try block as it is expected that there be some arithmetic exception and possibly a Divide by Zero exception. Two catch blocks are placed for the try block of code. One is DivideByZeroException and other one is System.Exception. Inside each catch block, the exception object caught was used to display the Exception message, and function call stack of where the exception raised. Below is the code:

3) The calculate is just an intermediate function which makes a call to Divide. Note how the stack rewind and exception bubbling is happening. Below is the function which makes a call to divide, and does not have any Exception handler code:

4) The divide function tries to divide a number by zero. The .NET environment detects the situation and raises the exception for us. Note there is no throw statement here. In my previous examples (actually in the previous part), I forced the system to throw an Exception for my demonstration purpose. We usually use the throw statement for Custom defined exceptions. The .NET environment is smart enough to detect the exception at right time and raise it. Below is the code for divide:

7. Closing Notes

The DivideByZeroException thrown in the Divide function is caught by the StartProgram function. Then the exception object is matched against the first catch block. As there is a match, the exception enters that catch block.

What happens if System.Exception catch block is before the DivideByZeroException? We do enter the System.Exception catch block even though a more perfect match exists. Because, the exception caught is matched from top to bottom. As the System.Exception is on the top (that is; Before DivideByZero) and the caught Exception DivideByZeroException is polymorphically a System.Exception the execution control just enters the System.Exception catch block.

So always keep in mind to place more specific catch statement first and move down with more Generalized Exceptions. Look at the code below how a smart developer placed his catch block based on what his Team Lead told.

Lead: “The code block may raise a DivideByZeroException or Any ArithmeticException. It is possible to have FileNotFound Exception also. These are the possibilities of Exception I am seeing when I am reviewing your code. But, for safety, try to handle all exceptions in the world and it is OK if it is not more specific”.

That's all, the Lead went to a meeting.

Forget what meeting he is going for, see how the developer placed his catch block:

try
{
// The set of code and function here
// reviewed by an Experienced lead.
}
catch (System.FileNotFoundException Ex)
{
//File Not Found Exception is Different from Divide by zero.
//Look at the Inheritance hierarchy in MSDN for FileNotFoundException
//and DivideByZeroException.
//So I don't care Which one First, FileNotFond or DivideByZero
}
catch( System.DivideByZeroException Ex)
{
//Divide by Zero Exception. Need More Specialized care
}
catch (System.ArithmeticException Ex)
{
// For any ArithmaticException except DivideByZero. Because I already handled it
// before this catch statement
}
catch(System.Exception Ex)
{
//I am not expecting that this would Occur. As per my Lead
//I placed it for safe to handle any Exception in the world
// That derived from Exception.
}
finally
{
//Clean-up code
}

Look at the comments and I hope it is self-explanatory.

See you all, I hope this article explained something to you about Exception Handling in C#.

jgauffin gave a nice point about why you should catch only the specific exception. Look at his Blog (jgauffin) for more information: Click here to visit.

"The DivideByZeroException thrown in the Divide function is caught by the StartProgram function. Then the exception object is matched against the first catch block. As there is a match, the exception enters that catch block.

What happens if System.Exception catch block is before the DivideByZeroException? We do enter the System.Exception catch block even though a more perfect match exists. Because, the exception caught is matched from top to bottom. As the System.Exception is on the top (that is; Before DivideByZero) and the caught Exception DivideByZeroException is polymorphically a System.Exception the execution control just enters the System.Exception catch block."

But it is not possible because we can not define System.Exception catch block before the DivideByZeroException catch block otherwise it will generate an error "A previous catch clause already catches all exceptions of this or of super type".

I wrote that closing notes as General rule of thumb which is useful for any object oriented language. However your statement "A previous catch clause already catches all exceptions of this or of super type" tells more obvious to C# which is required for the article. Which version of Dot net you used?

The information provided by you is useful for the readers of the article. Thanks. (Up voted your comment )

I'm going to give it a 5 because it is, indeed, very well written and illustrated - but I would also caution about the catching EVERY exception. I suggest you update the article's contents for future readers so that this does not mislead them inadvertently, okay? Otherwise - good job sir! )

I was working on my exception handling today and just got my Code Project weekly summary newsletter. Your article helped clarify some points. My goal in reviewing my exception handling was to improve the design so that I handle all possible anticipated exceptions with the least amount of redundant code. I see the bubbling and throwing as tools but I am not sure how to accomplish this with the minimum amount of code.

In some of my methods I have more exception handling code than application code. Any suggestions?

One thing to point out in your article may be that: if you throw an exception in a method from a catch block it will only be handled if there is another catch block to bubble up to. In other words, throwing to a "catch (DivideByZero)" from a "catch (DivideByZero)" will NOT reuse that "catch (DivideByZero)". Another catch for the exception needs to be present to bubble up to.