Exception Handling in C#
C# includes exception handling at the class level. Each type of error that occurs has an Exception class associated with it.
So for example, if you divide a number by zero you will get an error. The .net Framework includes a class in the System namespace called DivideByZeroException which stores all the information relating to a divide by zero error.
Each type of error condition has its own Exception class and each one inherits from a base class called Exception.
You can use this base class to trap unknown errors and you can inherit from it to create custom exception handling classes.
Note that using try catch will slow the program down a little. You should place your try catch only around code where you may get errors.
Unhandled Exceptions
If an error occurs you can get an error message which is ugly and unhelpful to a user. The message may be helpful to you as a programmer but does not look good to a user.
The error message will depend on the type of programming error. The example code below creates errors based on the user input.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace exceptions1
{
class Program
{
static void Main(string[] args)
{
string s;
int zero = 0;
Console.WriteLine("Enter A, B, or C");
s = Console.ReadLine().ToString().ToUpper();
switch (s)
{
case "A":
Console.WriteLine("Attempt to divide by zero");
Console.WriteLine("{0}", 20 / zero);
break;
case "B":
Console.WriteLine("Attempt to read from a non-existent file");
StreamReader sr = File.OpenText("agile.txt");
break;
case "C":
Console.WriteLine("Throw an exception yourself");
throw new FileNotFoundException();
break;
default :
Console.WriteLine("do nothing");
break;
}
Console.WriteLine("This is the end of the program");
}
}
}
Trying to Catch Errors
To catch errors, you include any code that you think might cause an error inside a try{} block and any code that you want to run trap errors in a catch {} block as shown in the next example :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace exceptions2
{
class Program
{
static void Main(string[] args)
{
string s;
int zero = 0;
Console.WriteLine("Enter A, B, or C");
try
{
s = Console.ReadLine().ToString().ToUpper();
switch (s)
{
case "A":
Console.WriteLine("Attempt to divide by zero");
Console.WriteLine("{0}", 20 / zero);
break;
case "B":
Console.WriteLine("Attempt to read from a non-existent file");
StreamReader sr = File.OpenText("agile.txt");
break;
case "C":
Console.WriteLine("Throw an exception yourself");
throw new FileNotFoundException();
break;
default:
Console.WriteLine("do nothing");
break;
}
}
catch
{
Console.WriteLine("An error occurred");
}
Console.WriteLine("This is the end of the program");
}
}
}
The above example uses catch on its own which will catch all error types. In this case you will not know what type of error occurred or where it took place.
To get some information about errors you should include the type of exception you are trying to catch in the catch {} block.
So replace the catch block of code with
catch (Exception e)
{
Console.WriteLine(“An error occurred: {0}”, e.Message);
}
The above code shows the most general Exception class being used.
When an error occurs in the try {} block the object e is created.
You can use the catch {} to provide an error message or do anything else that may be useful in your application.
Catching Different Types of Errors
You can test for errors of different types.
If you now replace the catch {} block with a set of catch {} blocks we can trap specific errors.
catch (DividebyZeroException e)
{
Console.WriteLine(“A divide by zero problem”);
}
catch(FileNotFoundException e)
{
Console.WriteLine(“No such file”);
}
catch
{
Console.WriteLine(“An error occurred”);
}
When an exception occurs, the error is checked against your list of catch {} blocks to see if there is a handler to handle the specific class of problem. The generic handler block at the end will catch all other exceptions in this program. So, the program cannot crash.
Doing something even after exceptions occur
There are times when you want to exit the program because of an exception, but where you want to do need to do one more thing before you exit such as closing a file or releasing an open network resource.
This can be achieved using the finally block as shown below :
catch
{
Console.WriteLine(“An error occurred”);
}
finally
{
Console.WriteLine(“This will run even when an exception occurs”);
}
The finally {} block is where code will be run immediately after an exception or after all the code is the try {} block has executed successfully.
Using Finally Without a Catch
It is valid code to have a try {} block and a finally {} but no catch {} blocks. In this case you are not handling an exception and you will still receive the standard error message but the code in your finally {} block will still run.
Try block inside another
You can put a try block inside another.
The behaviour when you have try{} block inside another depends on if you have a suitable catch{} block for the exception that occurs, and also the scope of the try blocks.