ARTICLE

Exception Handling: Part I

Posted by Sivaraman Dhamodaran Articles | Exception Handling C# November 06, 2010
This artcle shows how we handle exceptions, what is call stack rewind and Exception bubbing. At last discuss the importance of finally block.
Reader Level:
Download Files:
 

1. Exception

An Exception is an object of the Exception class. This Exception class is in the System.Exception name space. 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 exceptions we need to know two basic things:

  1. A failure has occured and throws an exception by packing the valid information.

  2. The exception is caught is by an Exception Handler.

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

 

class ExceptionsEx

{

            //001: Start the Program Execution.

            public void StartProgram()

            {

                        Console.WriteLine("Making Call to F1() " );

                        F1();

                        Console.WriteLine("Successfully returned from F1() " );

            }

 

            //002: Set of Function that calls each other

            public void F1()

            {

                        Console.WriteLine("Making Call to F2() " );

                        throw new System.Exception();

                        F2();

                        Console.WriteLine("Successfully returned from F2() " );

            }

            public void F2()

            {

                        Console.WriteLine("Inside F2 " );

            }

 

            //Client 001: Program Entry

            [STAThread]

            static void Main(string[] args)

            {

                        //Create the Object and start the Execution

                        ExceptionsEx app = new ExceptionsEx();

                        app.StartProgram();

            }

}

 

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 un-handled exception dialog. 


Pic01.jpg

 

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.

 

Pic02.jpg 

 

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

 

2. Handling an Exception

 

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

 

try

{

            //Some Code that may expected to raise an exception

}

catch

{

            //Raised exception Handled here

}

 

In the above skeleton any exception is handled. But, the main disadvantage is 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:

 

class ExceptionsEx

{

            //001: Start the Program Execution.

            public void StartProgram()

            {

                        Console.WriteLine("Making Call to F1() " );

                        try

                        {

                                    F1();

                        }

                        catch

                        {

                                    Console.WriteLine("Some Exception Occurred. I don't know what Exception it is and where it Occured. Sorry!");

                        }

                        Console.WriteLine("Successfully returned from F1() " );

            }

 

            //002: Set of Function that calls each other

            public void F1()

            {

                        Console.WriteLine("Making Call to F2() " );

                        throw new System.Exception();

                        Console.WriteLine("Successfully returned from F2() " );

            }

 

//Client 001: Program Entry

[STAThread]

static void Main(string[] args)

{

                        //Create the Object and start the Execution

            ExceptionsEx app = new ExceptionsEx();

                        app.StartProgram();

}

}

 

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 that happens if there are multiple nested function calls, and an exception occurrs in the fourth or fifth nested call. Look at the Picture below:

PicA.jpg 

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. Traveling back from F3->F2->F1 is known as Stack Unwind. An exception that occurred in F3 is handled in F1 even when there is no handler at F2; this is known as Exception Bubbling.

 

Below is the Example that demonstrates the Exception Bubbling

 

using System;

 

namespace ExceptionHandling

{

            class ExceptionsEx

            {

                        //001: Start the Program Execution.

                        public void StartProgram()

                        {

                                    Console.WriteLine("Making Call to F1() " );

                                    try

                                    {

                                                F1();

                                    }

                                    catch

                                    {

                                                Console.WriteLine("Some Exception Occurred. I don't know what Exception it is and where it Occured. Sorry!");

                                    }

                                    Console.WriteLine("Successfully returned from F1() " );

                        }

 

                        //002: Set of Function that calls each other

                        public void F1()

                        {

                                    Console.WriteLine("Making Call to F2() " );

                                    F2();

                                    Console.WriteLine("Successfully returned from F2() " );

                        }

                        public void F2()

                        {

                                    Console.WriteLine("Making Call to F2() " );

                                    F3();

                                    Console.WriteLine("Successfully returned from F2() " );

                        }

                        public void F3()

                        {

                                    Console.WriteLine("Inside F3 " );

                                    throw new System.Exception();

                        }

 

                        //Client 001: Program Entry

                        [STAThread]

                        static void Main(string[] args)

                        {

                                    //Create the Object and start the Execution

                                    ExceptionsEx app = new ExceptionsEx();

                                    app.StartProgram();

                        }

            }

} 

 

3. 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 travels 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 next couple of statement that will not get reached. Right?

 

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

 

try

{

}

catch

{

}

finally

{

}

 

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

 

 

PicB.jpg

 

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

 

Whether an Exception occurs or not the code inside a 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.

erver'>
Login to add your contents and source code to this article
post comment
     
COMMENT USING
PREMIUM SPONSORS
DynamicPDF™ product line allows you to dynamically generate PDF documents, merge PDF documents and add new content to existing PDF documents from within your applications.
Join a Chapter
SPONSORED BY
  • PDF reports have never been easier to create. With our included WYSIWYG Designer, you can layout your reports, set up your data source and let DynamicPDF ReportWriter do the rest.