When program is executing then at runtime error may be occur due to wrong data type conversion, passing invalid connection string, permission failed while opening a file and there are lots of condition.Error which is occurred at runtime is known as exception.

Exception will cause abnormal termination of program execution, if no exception handler present for a given exception, then the program terminate abnormally and stops execution with an error details, which is not good for user experience thankfully we have Exception handling in .NET. 

So in C#, exception is an event or object which is thrown at runtime. All exceptions the derived from System.Exception class. It is a runtime error which can be handled. If we don't handle the exception, it prints exception message and terminates the program.

Exception handling in C# uses the trycatch, and finally keywords to try actions that may not succeed, to handle failures when you decide that it is reasonable to do so, and to clean up resources afterward. 

Let's try to take an example which throws "System.IndexOutOfRangeException" exception when trying to get 7th(6th position) element from the size 6 array

using System;

namespace ExceptionHandlingCsharp
{
    class Program
    {
        public static void Main()
        {
            int[] table = new int[6] { 10, 11, 12, 13, 14, 15 };
            int idx = 6;

            AccessingElement(table, idx);
        }

        public static void AccessingElement(int[] table, int idx)
        {
            Console.WriteLine("Accessing element {0}: {1}",
                               idx, table[idx]);
        }
    }
}

exception-handling-in-csharp-min.png

When executed the above program in Console application, it got terminated due to "System.IndexOutOfRangeException", therefore effect of the WriteLine command in line 17 never occurs, because the error happens before WriteLine takes effect.

So, we can save our program from being terminated using try-catch & finally blocks in C# and show some useful message of error to our end user.

try catch block in C#

The try section contains the statements that might throw an exception. A catch block used to handle exception which is raise in try block.

When our code executes and on that time, if any line of statement of try block throwing an exception, then following line of execution statement are ignored and control directly jumps to catch block and execute catch block.

A try block can be followed by multiple catch sections. Writing an exception class with in the catch block is optional.

Simple try-catch block syntax

      // Simple try-catch block
        try
        {
            // Your logical codes, which can throw error
        }
        catch (Exception Ex)
        {
           //Do something when error is Caught
           //you can get Error message using Ex.Message
        }

Let's try to use the above code again, using Try-catch block to handle exception

using System;

namespace ExceptionHandlingCsharp
{
    class Program
    {
        public static void Main()
        {
            int[] table = new int[6] { 10, 11, 12, 13, 14, 15 };
            int idx = 6;

            try
            {
                AccessingElement(table, idx);
            }
            catch(Exception ex)
            {
                Console.WriteLine("Error Found, details as below ");
                Console.WriteLine(ex);
            }
        }

        public static void AccessingElement(int[] table, int idx)
        {
            Console.WriteLine("Accessing element {0}: {1}",
                               idx, table[idx]);
        }
    }
}

Output:

csharp-try-catch-example-min.png

As you can see, Now we have got complete error details in our console and user can know about the issue.

Multiple try-catch blocks

//Multiple catch blocks for one try block
try 
{
    // Your logical codes
} 
catch (DivideByZeroException Ex) {
    
} 
catch (OverflowException Ex) {
    
} 
catch (FormatException Ex) {
    
}

Nested try-catch blocks

        // Nested try-catch block
        try
        {
            // Your logical codes
            try
            {
                // Your logical codes
            }
            catch (Exception Ex)
            {
 
            }
        }
        catch (Exception Ex)
        {

        }

If catch block is used without an exception class then it is known as generic catch block,as show below

// generic catch block
        try
        {
            // Your logical codes
        }
        catch
        {
            Console.Write("Exception raised in the application");
        }

Finally block

A finally block enables you to clean up actions that are performed in a try block.

The finally block can be used to release resources such as a file streams, database connections and graphics handlers without waiting for the garbage collector in the runtime to finalize the object.

C# finally block is used to execute important code which is to be executed whether exception is handled or not. It must be preceded by catch or try block.

The finally section always executes, even if the program leaves the try and catch sections because of any reasons:

  • try section executes and no catch section execute.
  • try section raised exception and catch section handle it.
  • try section raised exception and that not caught by any catch section
  • catch section throw an exception
  • try section uses a return statement to exit the method
  • catch section uses return statement to exit the method

Syntax

 // try-catch-finally blocks
        try
        {
            // Your logical codes
        }
        catch (Exception Ex)
        {
 
        }
        finally
        {
 
        }

let's take an example

using System;

namespace ExceptionHandlingCsharp
{
    class Program
    {
        public static void Main()
        {
            try
            {
                int a = 10;
                int b = 0;
                int x = a / b;
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
            finally
            {
                Console.WriteLine("Finally block is executed");
            }
            Console.WriteLine("Some more code here");
        }

       
    }
}

Output:

System.DivideByZeroException: Attempted to divide by zero.
Finally block is executed
Rest of the code

throw in C#

An exception can be raised manually by using the throw keyword. Any type of exceptions which is derived from Exception class can be raised using the throw keyword.

So, If you want to catch the exception in catch block, then you can do it, by throwing it using the throw keyword at the end of catch block & that's how exception can be explicitly generated by a program using throw keyword.

Let's take a look on an example, the following example uses the throw statement to throw an IndexOutOfRangeException if the argument passed to a method named GetNumber does not correspond to a valid index of an internal array.

 static int[]  numbers = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
        public  static int GetNumber(int index)
        {
            if (index < 0 || index >= numbers.Length)
            {
                throw new IndexOutOfRangeException();
            }
            return numbers[index];
        }

Method callers then use a try-catch or try-catch-finally block to handle the thrown exception. The following example handles the exception thrown by the GetNumber method.

using System;

namespace ExceptionHandlingCsharp
{
    class Program
    {
        public static void Main()
        {
          
            int index = 10;
            try
            {
                int value = GetNumber(index);
                Console.WriteLine($"Retrieved {value}");
            }
            catch (IndexOutOfRangeException e)
            {
                Console.WriteLine($"{e.GetType().Name}: {index} is outside the bounds of the array");
            }
                       
        }
        static int[]  numbers = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
        public  static int GetNumber(int index)
        {
            if (index < 0 || index >= numbers.Length)
            {
                throw new IndexOutOfRangeException();
            }
            return numbers[index];
        }

    }
}

Output:

 IndexOutOfRangeException: 10 is outside the bounds of the array

Exception rethrowing

throw can also be used in a catch block to re-throw an exception handled in a catch block. In this case, throw does not take an exception operand.

It is most useful when a method passes on an argument from a caller to some other library method, and the library method throws an exception that must be passed on to the caller.

Example:

using System;

namespace ExceptionHandlingCsharp
{
    class Program
    {
        public static void Main()
        {
            try
            {
                CheckInt();
            }
            catch (Exception Ex)
            {
                Console.WriteLine("Message -" + Ex.Message );
                Console.WriteLine("Source - " + Ex.Source );
                Console.WriteLine("StackTrace - " + Ex.StackTrace );
            }

        }
        public static void CheckInt()
        {
            try
            {
                int a = Convert.ToInt32("one");
            }
            catch (Exception Ex)
            {
                throw Ex;
            }
        }

    }
}

Output:

Message -Input string was not in a correct format.
Source - ExceptionHandlingCsharp
StackTrace -    at ExceptionHandlingCsharp.Program.CheckInt() in C:\Users\CT\source\repos\ExceptionHandlingCsharp\ExceptionHandlingCsharp\Program.cs:line 29
   at ExceptionHandlingCsharp.Program.Main() in C:\Users\CT\source\repos\ExceptionHandlingCsharp\ExceptionHandlingCsharp\Program.cs:line 11

Exception Properties

Property Description
Message A message explaining about the exception in general terms.
Source The name of the application or object that caused the exception.
StackTrace A string representation of the program's stack trace when the exception occurred. It also containing code's line number that generated exception.
TargetSite Information about the method that throw the exception.
InnerException An exception object that gives more information about the exception
Data A collection of key-value pairs that give information about the exception.
Helplink A link to a help file associate with the exception.
HResult A numeric code describing the exception in general terms.

Exception Overview

Exceptions have the following properties:

  • Exceptions are types that all ultimately derive from System.Exception.
  • Use a try block around the statements that might throw exceptions.
  • Once an exception occurs in the try block, the flow of control jumps to the first associated exception handler that is present anywhere in the call stack. In C#, the catch keyword is used to define an exception handler.
  • If no exception handler for a given exception is present, the program stops executing with an error message.
  • Do not catch an exception unless you can handle it and leave the application in a known state. If you catch System.Exception, rethrow it using the throw keyword at the end of the catch block.
  • If a catch block defines an exception variable, you can use it to obtain more information about the type of exception that occurred.
  • Exceptions can be explicitly generated by a program by using the throw keyword.
  • Exception objects contain detailed information about the error, such as the state of the call stack and a text description of the error.
  • Code in a finally block is executed even if an exception is thrown. Use a finally block to release resources, for example to close any streams or files that were opened in the try block.
  • Managed exceptions in the .NET Framework are implemented on top of the Win32 structured exception handling mechanism.

That's it, hope you have clear understanding of Exception handling & try-catch-finally keywords in C#, feel free to post your views or questions related to this post below.