Exception Handling in C#
Tags: csharp, exceptionhandling, cleancode
Published: 2020-10-21 17:41:02

The original post was from my site [here](https://www.grantwatson.app/blog/csharp-exception-handling).

In this post, I will cover, in short, C#’s exception handling. Other than syntax, you can take these principles forward with many OOP languages and utilize them. What are exceptions, and why should we as developers even consider handling them? Consider first what an exception is. Specifically in C#, an exception is a response to an exceptional circumstance that arises while a program is running, such as an attempt to divide by zero. Exceptions provide a way to transfer control from one part of a program to another. Another well thought definitions of an exception is that it is defined as an event that occurs during the execution of a program that is unexpected by the program code.

Your code runs into an exception when you try to give it a value, or expect an output where either is not known within the program. Exception handling allows a graceful way to handle unwanted events, an exception so that the program code still makes sense to the user.

The Anatomy of C# Exceptions
Exceptions allow an application to transfer control from one part of the code to another. When an exception is thrown, the current flow of the code is interrupted and handed back to a parent try catch block. C# exception handling is done with the follow keywords: try, catch, finally, and throw

Try: Used to define a try block. This block holds the code that may throw an exception

Catch: Used to define the catch block. This block catches the exception thrown by the try block

Finally: Used to define the finally block. This block holds the default code

Throw: Used to throw an exception manually

Example 1:

using System;

namespace ErrorHandlingApplication {
   class DivNumbers {
      int result;

      DivNumbers() {
         result = 0;
      }

      public void division(int num1, int num2) {
         try {
            result = num1 / num2;
         } catch (DivideByZeroException e) {
            Console.WriteLine("Exception caught: {0}", e);
         } finally {
            Console.WriteLine("Result: {0}", result);
         }
      }

      static void Main(string[] args) {
         DivNumbers d = new DivNumbers();
         d.division(25, 0);
         Console.ReadKey();
      }
   }
}
Output

Above, we have set the values in a try, and then caught exceptions in the catch. Finally is also set to show the result

try {
   result = num1 / num2;
} catch (DivideByZeroException e) {
   Console.WriteLine("Exception caught: {0}", e);
} finally {
   Console.WriteLine("Result: {0}", result);
}
Example #2: Exception Filters
One of the new features in C# 6 was exception filters. They allow you have even more control over your catch blocks and further tailor how you handle specific exceptions. This can help you fine-tune exactly how you handle exceptions and which ones you want to catch.

Before C# 6, you would have had to catch all types of a WebException and handle them. Now you could choose only to handle them in certain scenarios and let other scenarios bubble up to the code that called this method. Here is a modified example with filters:

WebClient wc = null;
try
{
   wc = new WebClient(); //downloading a web page
   var resultData = wc.DownloadString("http://google.com");
}
catch (WebException ex) when (ex.Status == WebExceptionStatus.ProtocolError)
{
   //code specifically for a WebException ProtocolError
}
catch (WebException ex) when ((ex.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.NotFound)
{
   //code specifically for a WebException NotFound
}
catch (WebException ex) when ((ex.Response as HttpWebResponse)?.StatusCode == HttpStatusCode.InternalServerError)
{
   //code specifically for a WebException InternalServerError
}
finally
{
   //call this if exception occurs or not
   wc?.Dispose();
}
Common .NET Exceptions
Proper exception handling is critical to all application code. There are a lot of standard exceptions that are frequently used. The most common being the dreaded null reference exception. These are some of the common C# Exception types that you will see on a regular basis.

The follow is a list of common .NET exceptions:

System.NullReferenceException – Very common exception related to calling a method on a null object reference

System.IndexOutOfRangeException – Occurs attempting to access an array element that does not exist

System.IO.IOException – Used around many file I/O type operations

System.Net.WebException – Commonly thrown around any errors performing HTTP calls

System.Data.SqlClient.SqlException – Various types of SQL Server exceptions

System.StackOverflowException – If a method calls itself recursively, you may get this exception

System.OutOfMemoryException – If your app runs out of memory

System.InvalidCastException – If you try to cast an object to a type that it can’t be cast to

System.InvalidOperationException – Common generic exception in a lot of libraries

System.ObjectDisposedException – Trying to use an object that has already been disposed

Here are a few articles to go into further detail of best practices:

Exception Handling

Microsoft Docs on Best Practices