Microsoft.NET

……………………………………………….Expertise in .NET Technologies

Best Practices for Handling Exceptions

Posted by Ravi Varma Thumati on January 23, 2009

This article shall explain some of the best practices when you deal with exceptions.

 

Exception is an expensive process, for this reason, you should use exceptions only in exceptional situations and not to control regular logic flow.

 

For example:

void EmpExits ( string EmpId)
{
    //… search for employee
   
if ( dr.Read(EmpId) ==0 ) // no record found, ask to create
   
{
        throw( new Exception(“Emp Not found”));
    }
}

The best practice is :

bool EmpExits ( string EmpId)
{
    //… search for Product
   
if ( dr.Read(EmpId) ==0 ) // no record found, ask to create
   
{
        return false

    }
}

 

Avoid exception handling inside loops, if its really necessary implement try/catch block surrounds the loop.

 

Adopt the standard way of handling the exception through try, catch and finally block. This is the recommended approach to handle exceptional error conditions in managed code; finally blocks ensure that resources are closed even in the event of exceptions.

 

For example:

SqlConnection conn = new SqlConnection(“…”);
try
{
    conn.Open();
    //.some operation
    // … some additional operations
}
catch(¦)
{
    // handle the exception
}
finally
{
    if (conn.State==ConnectionState.Open)
    conn.Close(); // closing the connection
}

 

Where ever possible use validation code to avoid unnecessary exceptions .If you know that a specific avoidable condition can happen, precisely write code to avoid it. For example, before performing any operations checking for null before an object/variable can significantly increase performance by avoiding exceptions.

 

For example:

double result = 0;
try
{
    result = firstVal/secondVal;
}
catch( System.Exception e)
{
    //handling the zero divided exception
}

This is better then the above code

double result = 0;
if(secondVal >0)
result = firstVal/secondVal;
else
result = System.Double.NaN;

 

Do not rethrow exception for unnecessary reason because cost of using throw to rethrow an existing exception is approximately the same as creating a new exception and rethrow exception also makes very difficult to debug the code.

 

For example:

try
{
    // Perform some operations ,in case of throw an exception
}
catch (Exception e)
{
    // Try to handle the exception with e
   
throw;
}

 

The recommended way to handle different error in different way by implement series of catch statements this is nothing but ordering your exception from more specific to more generic for example to handle file related exception its better to catch FileNotFoundException, DirectoryNotFoundException, SecurityException, IOException, UnauthorizedAccessException and at last Exception.

 

.NET errors should be capture through SqlException or OleDbException.

  • Use the ConnectionState property for checking the connection availability instead of implementing an exception.
     
  • Use Try/Finally more often, finally provides option to close the connection or the using statement provides the same functionality.
     
  • Use the specific handler to capture specific exception, in few scenarios if you know that there is possibility for a specific error like database related error it can be catch through SqlException or OleDbException as below.

    try
    { …
    }
    catch (SqlException sqlexp) // specific exception handler
    { …
    }
    catch (Exception ex) // Generic exception handler
    { …
    }

Its recommend to use “Exception Management Application Block” provided by Microsoft. It is a simple and extensible framework for logging exception information to the event log or you can customize to write the exception information to other data sources without affecting your application code and implemented all best practices and tested in Microsoft Lab.

 

Exception Handling

Exceptions in C# provide a structured and type-safe way of handling both system level and application level error conditions. The exception mechanism in C# is very similar to that of C++, with a few important differences.

Exceptions in C# provide a structured and type-safe way of handling both system level and application level error conditions. The exception mechanism in C# is very similar to that of C++, with a few important differences.

In C#, all exceptions must be represented by an instance of a class type derived from System.Exception

Causes of exceptions:

  • Certain exceptional conditions that arise during the processing of C# statements and expression cause an exception in certain circumstances when the operation cannot be completed normally. For example, an integer division operation throws a System.DivideByZeroException if the denominator is zero.
  • A throw statement throws an exception immediately and unconditionally. Control never reaches the statement immediately following the throw.

Handling Exceptions: 

Consider the following code:

List: 1 Test1.cs 

using System;
class Test
{
public static void Main(string[] args)
{
int i = 10/Int32.Parse(args[0]);
Console.WriteLine(i);
}
}

Now when we run the above program like

test 5

It will print 2 on console. 

But suppose if we run it like

test  or  test hello

Then in that case program will crash. We need to handle these situations by modifying our code. 

Exceptions are handled by try-catch statement. 

List: 2 Test2.cs

using System;
class Test
{
public static void Main(string[] args)
{
try
{
int i = 10/Int32.Parse(args[0]);
Console.WriteLine(i);
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
}
}

Now, when we run above program, there will be many possibilities. 

Scenario 1:
we run it like test 5. output will be 2. so if try block is executed smoothly, catch block will never execute.

Scenario 2:
We run it like test. In this case output will be a string “An exception of type System.IndexOutOfRangeException was thrown”. This output is coming from catch block. Thus if there is any runtime problem with the try block, control will be transferred to the catch block and no further statements in try block will be executed.

Scenario 3:
We run it like test hello. In this case output will be a string “The input string is not in correct format.”

Scenario 4:
We run it like test 0. In this case output will be a string “Attempt to divide by zero”

Scenario 5:
We run it like test 1212121212121212. In this case output will be a string “Value was either too large or too small for an Int32”.

So, there are four situations need to be handled. Consider the following code:

List: 3  test3.cs 

using System;
class Test3
{
public static void Main(string[] args)
{
try
{
int i = 10/Int32.Parse(args[0]);
}
catch(IndexOutOfRangeException e)
{
Console.WriteLine(e.Message);
}
catch(FormatException e)
{
Console.WriteLine(e.Message);
}
catch(DivideByZeroException e)
{
Console.WriteLine(e.Message);
}
catch(OverflowException e)
{
Console.WriteLine(e.Message);
}
}
}

Four catch blocks are included in this code. To make the program simple enough,  all the catch blocks content is kept same. So depending upon the runtime situation, appropriate catch block will be executed.

Consider the following code:

List: 4  Test4.cs

using System;
class Test
{
public static void Main(string[] args)
{
try
{
int i = 10/Int32.Parse(args[0]);
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
finally
{
Console.WriteLine(“This is finally block”);
}
}
}

This is the example of try-catch-finally block. The execution will be either entire try block and then finally block, or exception in try block-catch block-finally block. Thus finally block will execute even if exception occurs or not.

Common Exception Classes:

The following exceptions are thrown by certain C# operations.

 

System.OutOfMemoryException

Thrown when an attempt to allocate memory (via new) fails.

System.StackOverflowException

Thrown when the execution stack is exhausted by having too many pending method calls; typically indicative of very deep or unbounded recursion.

System.NullReferenceException

Thrown when a null reference is used in a way that causes the referenced object to be required.

System.TypeInitializationException

Thrown when a static constructor throws an exception, and no catch clauses exists to catch in.

System.InvalidCastException

Thrown when an explicit conversion from a base type or interface to a derived types fails at run time.

System.ArrayTypeMismatchException

Thrown when a store into an array fails because the actual type of the stored element is incompatible with the actual type of the array.

System.IndexOutOfRangeException

Thrown when an attempt to index an array via an index that is less than zero or outside the bounds of the array.

System.MulticastNotSupportedException

Thrown when an attempt to combine two non-null delegates fails, because the delegate type does not have a void return type.

System.ArithmeticException

A base class for exceptions that occur during arithmetic operations, such as DivideByZeroException and OverflowException.

System.DivideByZeroException

Thrown when an attempt to divide an integral value by zero occurs.

System.OverflowException

Thrown when an arithmetic operation in a checked context overflows.

 

Advertisements

4 Responses to “Best Practices for Handling Exceptions”

  1. Gayathri said

    hai sir,
    thanking you sir because this kind of opportunites to given for the students. these are very helpful for the students

  2. You actually make it seem really easy with your presentation but I to find this topic to be actually something which I feel I would by no means understand. It kind of feels too complicated and very vast for me. I’m taking a look ahead to your subsequent post, I will try to get the dangle of it!

  3. I have to admit that i typically get bored to learn the whole thing however i feel you’ll be able to add some value. Bravo !

  4. Dan Baff said

    What a lovely blog page. I will certainly be back. Please maintain writing!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: