Exception handling
using System;
public class zzz
{
public static void Main()
{
yyy a = new yyy();
a.abc();
Console.WriteLine("After abc");
Console.WriteLine("At end");
}
}
class yyy
{
public void abc()
{
Console.WriteLine("Start abc");
Console.WriteLine("End abc");
}
}
Start abc
End abc
After abc
At end
A simple program, we create a instance of the class yyy and call the function abc from it. All the WriteLine functions get called in the order we expected them to. We now add a single line of code to the abc function.
public void abc()
{
Console.WriteLine("Start abc");
throw new Exception();
Console.WriteLine("End abc");
}
Start abc
Unhandled Exception: System.Exception: Exception of type 'System.Exception' was
thrown.
at yyy.abc()
at zzz.Main()
Now only one WriteLine the first one gets called. The keyword throw throws an exception which is another way of say something unexpected happened. This could be an error or some thing very benign. The throw requires the name of a class which in our case is Exception. It is the throw keyword that shows the message box telling us that something wrong happened. In our case our program quits out. We change one line again as
throw new Exception("Vijay Mukhi");
Start abc
Unhandled Exception: System.Exception: Vijay Mukhi
at yyy.abc()
at zzz.Main()
Whatever we specify in the constructor to the Exception class is displayed as a helpful message to tell us what went wrong. The problem is that we have no control over what goes on.
public static void Main()
{
try
{
yyy a = new yyy();
a.abc();
Console.WriteLine("After abc");
}
catch(Exception e)
{
Console.WriteLine("In Exception " );
}
Console.WriteLine("At end");
}
Start abc
In Exception
At end
We add a try and catch block. The try encompasses the code we want to handle exceptions for. The catch catches the exception so that we get no dialog box. Thus the code after abc does not get called, the code in the exception gets called and the code after the catch gets called. Thus no code after the function that throws the exception will get called. This is how we can handle exceptions ourselves, use a try catch block
Console.WriteLine("In Exception " + e.ToString());
Start abc
In Exception System.Exception: Vijay Mukhi
at yyy.abc()
at zzz.Main()
At end.
By displaying the exception object e we get the same error string that we got earlier namely the functions that called the exception which is called the caller stack.
public void abc()
{
Console.WriteLine("Start abc");
throw new System.IO.IOException("Vijay Mukhi");
Console.WriteLine("End abc");
}
Start abc
In Exception System.IO.IOException: Vijay Mukhi
at yyy.abc()
at zzz.Main()
At end
The Exception class handles all exceptions and is it is the generic base class for all exceptions. The .net framework gives us a zillion exception handling classes, whenever a IO Exception occurs we should throw the Io exception instead of the generic exception .This is why the error show that a IoException has been thrown.
throw new IndexOutOfRangeException("vijay Mukhi");
Start abc
In Exception System.IndexOutOfRangeException: vijay Mukhi
at yyy.abc()
at zzz.Main()
At end
Whenever we have an array index out of bounds we get the above exception thrown. In real life throw an exception that is appropriate. The other problem is that the same catch handles all the exceptions. Depending upon the exception thrown we would like our own catch to be called.
public static void Main()
{
try
{
yyy a = new yyy();
a.abc();
Console.WriteLine("After abc");
}
catch(Exception e)
{
Console.WriteLine("In Exception " + e.ToString());
}
catch ( IndexOutOfRangeException e)
{
Console.WriteLine("In IndexOutOfRangeException " + e.ToString());
}
Console.WriteLine("At end");
}
a.cs(16,9): error CS0160: A previous catch clause already catches all exceptions of this or a super type ('System.Exception')
The class Exception will catch all the exceptions including IndexOutOfRange and hence the next catch has no meaning. Thus we get an error and to remove the error we interchange the order of exceptions.
public static void Main()
{
try
{
yyy a = new yyy();
a.abc();
Console.WriteLine("After abc");
}
catch ( IndexOutOfRangeException e)
{
Console.WriteLine("In IndexOutOfRangeException " + e.ToString());
}
catch(Exception e)
{
Console.WriteLine("In Exception " + e.ToString());
}
Start abc
In IndexOutOfRangeException System.IndexOutOfRangeException: vijay Mukhi
at yyy.abc()
at zzz.Main()
At end
As we are throwing an index exception as we have such a catch for the exception it gets called. When we throw an IoException, we are not specifically catching such a exception and thus it falls down to the generic Exception catch clause. Thus all exceptions not specially handled will be caught by the last catch which should always be the generic exception class.
If we remove the last generic exception catch and change the throw to IOException, then we see the messy dialog box as we are not handling the exception. Thus all exceptions not handled by us are handled by the system. This is why we need to place the default exception class last.
public static void Main()
{
try
{
yyy a = new yyy();
a.abc();
Console.WriteLine("After abc");
}
catch ( IndexOutOfRangeException e)
{
Console.WriteLine("In IndexOutOfRangeException " + e.ToString());
}
catch(Exception e)
{
Console.WriteLine("In Exception " + e.ToString());
}
finally
{
Console.WriteLine("In finally ");
}
Console.WriteLine("At end");
}
Start abc
In IndexOutOfRangeException System.IndexOutOfRangeException: vijay Mukhi
at yyy.abc()
at zzz.Main()
In finally
At end
We now introduce the finally clause. The finally clause gets called after the catch gets called. We comment out the throw in the abc function and yet finally gets called. We then write a return in the first catch first line, finally yet gets called but the WriteLine does not get called. Thus come what happens finally always gets called and we place code here that should get called always at the end of try catch block.
class yyy
{
public void abc()
{
Console.WriteLine("Start abc");
throw new aaa();
Console.WriteLine("End abc");
}
}
class aaa : Exception
{
public aaa()
{
}
Start abc
In Exception aaa: Exception of type 'aaa' was thrown.
at yyy.abc()
at zzz.Main()
At end
An exception is simply a class derived from the class Exception. Thus aaa is a new exception as it is derived from the class Exception. It is so simple to create an exception. Now lets add a parameter to the exception aaa.
throw new aaa("Vijay");
class aaa : Exception
{
public aaa(string a) : base(a)
{
}
}
Start abc
In Exception aaa: Vijay
at yyy.abc()
at zzz.Main()
At end
The base keyword calls the base class constructor, if we do not use this keyword the constructor with no parameter gets called. This is how we pass parameters to our own exception. What ever we do with the other exception we can do with ours. In the good old days of C programming we would call functions to do our job. These functions would return values denoting success or failure. There was however no consistency in what values were success or failure. In Unix –1 was considered failure, in windows 0 was success. Some functions like fopen returned 0 for failure.
The other problem was that if had to check the return value for each function. Thus if we called 30 functions we had to check for error 30 times, one for each function. There was no central place for error handling, it was spread all over your code. The third issue was that in constructors we write lots of code and they do not return values. Thus how do constructors tell us about errors in code.
The way out is to have the try and catch mechanism to trap exceptions. Things go wrong the function throws an exception, the other side catches it. If he does not the system is always there.