Exception Handling in C#

So, let's start without any delay by looking at an example where we will create a console application that can read the contents of a text file and display it on the console window.

In my E:\ drive, I have a folder called “Test” that has a text file named “HandlingException”.

HandlingException

The following is the content in that file.

Content in that file

We will write a C# program that will read the preceding contents and display it on the console window.

Let's flip to Visual Studio

Currently in my project, I have a class named “Program” that has a Main method.

Program

If we want to read from or write to a file, then we need to use some classes and their members that are present in the System.IO namespace.

So, import System.IO namespace into your project.

  1. using System;  
  2. using System.IO;  
  3.   
  4. namespace exceptionHandlinginCsharp {  
  5.    class Program {  
  6.       static void Main(string[] args) {  
  7.   
  8.       }  
  9.    }  
  10. }  
Within this namespace, there is a class called StreamReader.

What this class basically does is, it goes out to the file and then reads the contents of the file and streams it out for us.

So, let's create an instance of the StreamReader class in our Main method.
  1. using System;  
  2. using System.IO;  
  3.   
  4. namespace exceptionHandlinginCsharp {  
  5.    class Program {  
  6.       static void Main(string[] args) {  
  7.   
  8.          //backslash has a special meaning, it is an escape sequence character. So, in order to disable it we use verbatim literal "@".  
  9.          string path = @"E:\Test\HandlingException.txt";  
  10.         
  11.          //create an instance of StreamReader class and pass the path variable as a parameter argument in the StreamReader constructor.  
  12.          StreamReader sr = new StreamReader(path);  
  13.       }  
  14.    }  
  15. }  
StreamReader

What we want to do is, we want the StreamReader object to read until the end of the file and for that we can use the ReadToEnd method.
  1. static void Main(string[] args) {  
  2.    string path = @"E:\Test\HandlingException.txt";  
  3.    StreamReader sr = new StreamReader(path);  
  4.    sr.ReadToEnd();  
  5. }  
The return type of this ReadToEnd method is string. So, we can directly print the file contents on the console screen and in the end we close the stream, for that we use the Close() method.
  1. using System;  
  2. using System.IO;  
  3.   
  4. namespace exceptionHandlinginCsharp {  
  5.    class Program {  
  6.       static void Main(string[] args) {  
  7.          string path = @"E:\Test\HandlingException.txt";  
  8.          StreamReader sr = new StreamReader(path);  
  9.          Console.WriteLine(sr.ReadToEnd());  
  10.          sr.Close();  
  11.       }  
  12.    }  
  13. }  
Save and run

run


We have the contents of a file displayed on the console window.

Until now everything works fine. We have the expected output and we have also closed the connection successfully. So, the question that may occur to you is if everything works OK then why do we need exception handling?

But before moving any further, first let's understand what an exception is.

An exception is an unforeseen error that occurs during the execution of a program.

Now, let's say that by mistake someone (maybe you) deletes the HandlingException.txt file from the E:\ drive.

HandlingException folder

So, what will happen if you run the application now?

It will crash and will throw a FileNotFoundException. So, your application must be prepared to handle any kind of exception.

FileNotFoundException

To handle any kind of exception, we can use try/catch/finally block.

 

  • Try block: Contains the block of code that can throw an exception.

  • Catch block: It will catch the exception thrown from the try block.

  • Finally block: Can be used for closing the connection or releasing the resources.

 

  1. using System;  
  2. using System.IO;  
  3.   
  4. namespace exceptionHandlinginCsharp {  
  5.    class Program {  
  6.       static void Main(string[] args) {  
  7.          //path of the file  
  8.          string path = @"E:\Test\HandlingException.txt";  
  9.          //create an object of StreamReader and assign the value as null  
  10.          StreamReader sr = null;  
  11.   
  12.          //put the codes in the try block that can throw an exception  
  13.          try {  
  14.             sr = new StreamReader(path);  
  15.             Console.WriteLine(sr.ReadToEnd());  
  16.          }  
  17.          //the catch block will handle the exception  
  18.          catch (FileNotFoundException fileNotFoundEx) {  
  19.             //print a meaningful message to the front-end user. The FileName property gives the name of the file that cannot be found  
  20.             Console.WriteLine("File - " + fileNotFoundEx.FileName + " not found");  
  21.          } 
  22.          finally {  
  23.             //before closing the connection, check if the StreamReader object is null or not.  
  24.             //if it is not null then close the connection and if it is null then there is no point in closing the stream connection  
  25.             if (sr != null) {  
  26.                sr.Close();  
  27.             }  
  28.          }  
  29.       }  
  30.    }  
  31. }  
Note

It is always a good practice to release or close the connection in the finally because not matter what, the finally block is always executed.

Run the application

Run the application

So, we have handled the exception.

But what if we change the directory name from test to test1 and what will happen if we run the application after the modification?

Our application will crash and again it will throw an exception and this time it will throw a DirectoryNotFoundException.

Changing the directory from Test to Test1.

string path = @"E:\Test1\HandlingException.txt";

Run the application

Exception


To handle the preceding exception, we can add another catch block and this time we will use the base Exception class object that can handle many kinds of exceptions because directly or indirectly every other exception class inherits from this base Exception class.
  1. using System;  
  2. using System.IO;  
  3.   
  4. namespace exceptionHandlinginCsharp {  
  5.    class Program {  
  6.       static void Main(string[] args) {  
  7.          string path = @"E:\Test1\HandlingException.txt";  
  8.          StreamReader sr = null;  
  9.          try {  
  10.             sr = new StreamReader(path);  
  11.             Console.WriteLine(sr.ReadToEnd());  
  12.          }  
  13.          catch (FileNotFoundException fileNotFoundEx) {  
  14.             Console.WriteLine("File - " + fileNotFoundEx.FileName + " not found");  
  15.          }  
  16.          catch (Exception ex) {  
  17.             Console.WriteLine(ex.GetType().Name);  
  18.             Console.WriteLine("");  
  19.             Console.WriteLine(ex.Message);  
  20.          }  
  21.          finally {  
  22.             if (sr != null) {  
  23.                sr.Close();  
  24.             }  
  25.          }  
  26.       }  
  27.    }  
  28. }  
The GetType() method returns the type of the exception and the Name property gives us the name exception in a string format.

The Message property gives us some information about the reason for the exception.

Run the application

cmd


Note

An exception is actually a class present in the System namespace. This class has several properties that provide valuable information about exceptions.

The base exception catch block should always be last after all the specific exception blocks.