C# Exception Handling Tutorial with Code Examples

Exception handling is a Method to Handle Errors That May Occur During the Execution of a Program. This Tutorial Explains Exception Handling in C# with Code Examples:

Exception handling is used to make sure that the program flow is continued even if there is a runtime error. Exceptions are the objects that are thrown while encountering any runtime error.

If the exceptions are not handled, then C# will produce an exception message and will terminate the program, this is where exception handling comes into the picture.

=> Read Through The C# Guide For Beginners Here

Exception Handling In C#

What Are Exceptions?

Exceptions are unprecedented errors that may occur inside your program during runtime. Most of the time programmers can easily detect some of the errors like validation or null checking or while verifying some values.

But there are certain times when we cannot anticipate what or when an error will appear. For Example, let’s say I am looking for a file at a location. My program will run perfectly fine till the file is present and if somehow the file got deleted then my program will throw up an error.

Exceptions don’t occur on a regular basis but can still happen and you will always want to handle them carefully. To handle these we use exception handling.

Whenever an error occurs we say that it is thrown, “thrown” is an object from System.Exception class in C#. The System.Exception class offers different methods and properties that give details about the error that your program just encountered.

Like stack trace property that provides the stack for which the problem occurred or Message property that provides a description of the exception.

Keywords For Exception Handling

Exceptions offer a process to control a certain part of the program so that even if there is an exception in that part, then the program control is transferred to another part of the program. In C# exception handling is basically built around four keywords: throw, try, catch and finally.

throw

As we have already discussed throw is an object from System.Exception class in the C#. It allows the program to throw an error whenever it encounters one.

try

Try block encloses the block of the code that may cause the program to throw an exception. It is followed by one or more catch blocks.

catch

When try block encounters an exception, it provides the control to the catch block to catch the exception. The catch block can also contain a set of codes that the program needs to execute in case of an exception or it can just catch the exception and do nothing depending upon the scenario and requirement.

finally

The final block is used to execute a particular code snippet or instruction irrespective of the occurrence of an exception. Finally block is always executed, and it may be executed just after the trying block if the program doesn’t find any exception or it may be executed after the catch block once the program catches an exception.

Exception Classes Present In C#

All the exceptions in the C# are derived directly or indirectly from the System.Exception class.

Let us have a brief look at some of the most common exceptions:

  • System.IO.IOException: It handles any input and output related errors.
  • System.DividedByZeroException: Handles error thrown when a number is divided by zero.
  • System.NullReferenceException: Handles any error that may occur when a null object is referenced.
  • System.IndexOutOfRangeException: Handles error thrown when a program tries to access an index that is out of range for the array.
  • System.OutOfMemoryException: Handles error thrown due to insufficient memory presence.

Exception Handling In C#

C# has a very well-defined solution for handling any type of exception that may occur by using the try and catch block. Using this block, the core statement of the program can be separated from the other statements.

Example:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace ConsoleApp1
{
class Program
       {
             static void Main(string[] args)
             {
                    try
                    {
                          File.OpenRead("InvalidFile");
                     }
                     catch (FileNotFoundException ex)
                     {
                            Console.WriteLine(ex.ToString());
                     }

                   Console.ReadLine();
            }
     }
}

In, the above example, we have enclosed our code for opening a file under the try block. As we have not provided any valid file path, the code is ought to throw an error. Now, we have caught the error in our catch block. If the file does not exist in the given file path, then the code will throw a FileNotFoundException.

This exception will be caught by the catch block where we have already defined the expected exception. Now, let us imagine if our code throws some other exception, other than the one that we have already defined, then our block will not be able to catch it. To catch any generic exception, we will add another catch block.

Let us have a look at our updated code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;

namespace ConsoleApp1
{
class Program
       {
               static void Main(string[] args)
               {
                         try
                         {
                              File.OpenRead("InvalidFile");
                          }
                         catch (FileNotFoundException ex)
                         {
                             Console.WriteLine(ex.ToString());
                         }
                        catch (Exception e)
                       {
                             Console.WriteLine(e.ToString());
                        }
                       Console.ReadLine();
             }
        }
}

This generic catch block will be able to catch all the exceptions that may be thrown inside the try block. Now, let’s also add a finally block to complete this. To make it simple, let us just print a message using the finally block.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace ConsoleApp1
{
class Program
    {
              static void Main(string[] args)
              {
                        try
                        {
                            File.OpenRead("InvalidFile");
                        }
                       catch (FileNotFoundException ex)
                       {
                           Console.WriteLine(ex.ToString());
                       }
                      catch (Exception e)
                      {
                           Console.WriteLine(e.ToString());
                       }
                      finally
                      {
                           Console.WriteLine("Finally block executed");
                       }
            
                     Console.ReadLine();
              }
        }
}

Here, we have just added the finally block with a simple message. You can also add some custom statements in the block. But the overall structure of the program will remain similar to the one displayed here.

The Finally block will always be executed irrespective of whether there is an exception or not. The program will start from the try block and will then move directly to the finally block if there are no errors/exceptions. If it encounters an exception, then it will move to catch first and then will execute the final block.

Is there a condition when the finally block will not be executed?

As the name suggests the final block is executed at the end and is the final block of the code that will be executed. Finally block will always execute when the application is running. The only time when finally block will not execute is when the application crashes or is intentionally killed using process command.

Conclusion

If exceptions are not handled properly then they will cause error inside your program. If you haven’t used try/catch blocks anywhere inside your code, then your program will abort with a message showing the exception. To a generic user, this will be very difficult to trace the error back to the source code and resolve it.

Hence, it is always a good practice to provide exception handling in your program.

Sample Code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace ConsoleApp1
{
class Program
      {
               static void Main(string[] args)
               {
                         try
                         {
                              File.OpenRead("InvalidFile");
                          }
                        catch (FileNotFoundException ex)
                        {
                             Console.WriteLine(ex.ToString());
                        }
                       catch (Exception e)
                       {
                             Console.WriteLine(e.ToString());
                       }
                      finally
                      {
                            Console.WriteLine("Finally block executed");
                      }
            
                     Console.ReadLine();
             }
        }
}

=> See Our Complete C# Training Series Here