Introduction

C# and the .NET CLR use exceptions to indicate that an error condition has occurred during program execution. C# programs are under constant threat of running into some kind of trouble. As a program’s complexity grows, the possibility that something unusual would happen during its execution also gets higher. Exception handling helps applications trap exceptional events and respond to them in a predictable and robust manner.

This chapter shows and explains how to properly handle existing exceptions using try, catch, finally and throw blocks and how to create your own custom exceptions.

What is an Exception?

An Exception is an abnormal event or error condition existing in the technical execution of a particular statement that occurs during program execution. Exceptions can occur in the code you write (internal) or in an external code (DLL) that your program calls. Examples of error conditions include the following:

  • Network communication problems
  • Element access that is beyond the bound of an array
  • Running out of memory during program execution
  • Division by zero

An Exception Example

A common exception occurs when an integer is divided by zero, which then triggers an unhandled divide-by-zero exception as follows:

C# code

using System;
namespace ExceptionHandling
{
   class Program
   {
      static void Main(string[] args)
      {
         int x, y,Result;
         x = 10;
         y = 0;                                Unprotected block
         Result = x / y; //exception occur
         Console.WriteLine(Result);
      }
   }
}

Now place code that you think is likely to raise an exception in the try block, where it is protected from exceptions. Exceptions raised in the try block are trapped and the catch statements handle the exception, which consists of a catch filter (DivideByZeroException). After the exception is handled, the execution continues at the first statement after the catch statement:

C# code

Click to view larger image

CLR Exception Handling Mechanism

When an exception occurs in a program, the .NET framework runtime handles the problem by creating an exception object, populating it with information related to the error and passing it on to any fault handling code. C# does not force you to use try/catch blocks. The .NET runtime will try its best to search for a particular fault handler from the method call stack for an exception thrown in an unprotected block. If none is found, the .NET runtime generates an UnhandledExceptions event.

Exception Class Hierarchy

Using Try/Catch Blocks

To catch and handle exceptions, you need to place exception-throwing code in a try code. Then, you catch the resulting exception when it gets thrown in one or more catch blocks where error handling code is placed to properly deal with and recover from the exception. Optionally, you can add a finally block, whose code will always be executed regardless of whether or not an exception is thrown.

C# code

class Program
   {
      static void Main(string[] args)
      {
         int[] x=new int[2];

         try
         {
            x[0] = 10;
            x[1] = 20;

            //SUSPECTED CODE
            for (int i = 0; i             {
               Console.WriteLine(x[i]);
            }
         }
         catch (IndexOutOfRangeException err) // Exception handling
         {
            Console.WriteLine(err.Message);
         }
         Console.ReadKey();
      }
   }
 

In this program, we declare an array x of integer type with size 2, assign the values 10 and 20 to each array element, and display these values by using for loop. The for loop starts from 0 and is executed thrice due to the equal sign in the condition. However, the array size is 2 only and since the loop is executed three times, .Net runtime immediately throws an IndexOutOfRange error which is filter and handled by a catch block. The program output displays this error message:

Figure 1.1: Index Out of Range Error

NOTE: if you don’t mention a specific error, for instance IndexOutOfRange, and mention only Default Exception class in the catch block, then .NET runtime handles this by filtering it to an out of index error as follows:

C# code

          Try
            {
                ….
            }
            catch (Exception err) // Exception handling
            {
                Console.WriteLine(err.Message);
            }

Using Multiple Catch Blocks

If your code can potentially throw several types of exceptions, you can add multiple catch blocks, one for each exception type. When using multiple catch blocks, it will catch the most specific exceptions first and catch the most general exceptions last.

C# code

public static void Main(string[] args)
        {
            try
            {
                int total = 0;
                for (int i = 0; i < args.Length; i++)
                {
                    total += Int32.Parse(args[i]);

                }
                Console.WriteLine("you entered {0} arguments and their sum is {1} ",args.Length,total);
            }
            // Exception Handling
            catch (FormatException)
            {
                Console.WriteLine("Can't convert to Integer");
            }
            catch (IndexOutOfRangeException)
            {
                Console.WriteLine("Command Line Arguments is Not Entered");
            }
            catch (Exception)
            {
                Console.WriteLine("Unknown Error");
            }
            Console.ReadLine();
        }

This program has multiple catch blocks. It converts command-line arguments to integers, adds them, and prints the sum to the console.

Figure 1.2: Multiple catch statements

Using a Finally Block

In certain programming circumstances, you will want to ensure that a certain piece of code is executed in all cases regardless of whether or not an exception is thrown. A finally block is used for just this purpose.

C# code

public static void Main(string[] args)
        {
            try
            {
                if (args.Length > 0)
                {
                    Console.WriteLine(args[0]);
                }
            }
            // Exception Handling
            catch (IndexOutOfRangeException)
            {
                Console.WriteLine("Index out of Range");
            }

            finally
            {
                Console.WriteLine("Thank you for Using Exception Handling!");
            }
            Console.ReadLine();
        }

When you compile this program, no matter what happens when the program runs, the “Thank you…” message gets printed to the console:

Want to learn more?? The InfoSec Institute Web Application Penetration Testing Boot Camp focuses on preparing you for the real world of Web App Pen Testing through extensive lab exercises, thought provoking lectures led by an expert instructor. We review of the entire body of knowledge as it pertains to web application pen testing through a high-energy seminar approach.

The Web Application Penetration Testing course from InfoSec Institute is a totally hands-on learning experience. From the first day to the last day, you will learn the ins and outs of Web App Pen Testing by attending thought provoking lectures led by an expert instructor. Every lecture is directly followed up by a comprehensive lab exercise (we also set up and provide lab workstations so you don't waste valuable class time installing tools and apps). Benefits to you are:

  • Get CWAPT Certified
  • Learn the Secrets of Web App Pen Testing in a totally hands-on classroom environment
  • Learn how to exploit and defend real-world web apps: not just silly sample code
  • Complete the 83 Step "Web App Pen Test Methodology", and bring a copy back to work with you
  • Learn how perform OWASP Top 10 Assessments: for PCI DSS compliance

Figure 1.3: Finally block

Custom Exception class

In most cases, .NET’s built-in exception classes, combined with a custom message, should meet your exception handling requirements. However, in some cases, you might need exception types that are specific to the problem you are solving. Microsoft recommends that you consider the following when you design a custom exception class:

  • Create an exception class only if no exception class exists that satisfies your requirement.
  • Derive all custom exception classes from the ApplicationException or Exception class.
  • Implement these constructors with the signature shown as:

    C# code

public class NumberZeroExceptionMagic : ApplicationException
    {
        public NumberZeroExceptionMagic() : base() { }

        // The constructor that takes msg as a parameter
        public NumberZeroExceptionMagic(string msg) : base(msg) { }
    }

The following example divides two integer type numbers, but if we divide the denominator by zero,.NET runtime throws a DivideByZeroException. This situation can also be handled by a Custom Exception class as follows:

C# code

public class NumberZeroExceptionMagic : ApplicationException
    {
        public NumberZeroExceptionMagic() : base() { }
        // The constructor that takes msg as a parameter
        public NumberZeroExceptionMagic(string msg) : base(msg) { }
    }

    public class Test
    {
        static void Main(string[] args)
        {

            // Prompt the user to enter an integer
            Console.WriteLine("Please input an integer: ");

            // Try this block of code
            try
            {
                int Numerator = 10;
                // Store the input in x
                int x = Int32.Parse(Console.ReadLine());

                // If the number entered is 0...
                if (x == 0)
                {
                    // ...throw our custom exception with the following message parameter
                    throw new NumberZeroExceptionMagic("You are not allowed to enter number 0");
                }

                Console.WriteLine("Division: " + (Numerator/x).ToString());
            }
            // Catch the custom exception

            catch (NumberZeroExceptionMagic e)
            {
                // And display the error message
                Console.WriteLine("Exception: " + e.Message);
            }

            Console.ReadLine();
        }
    }

This program takes the input for denominator from the user. When the user enters any number except zero, the program shows the desired output, but in case the user enters zero, the exception is thrown by the custom exception class:

Figure 1.4: Custom Exception class