void SomefunctionX() {
throw new DivideByZeroException();
}
void SomeFunctionY() {
try
{
SomefunctionX();
}
catch (DivideByZeroException Ex) {
//Use the Ex here to get information
}
}
The example was shown just to understand where the object that is used in the catch block is coming from. Hope you now know the exception instance created on the throw statement caught in the catch block and used. Note that, the base class of DivideByZeroException is ArithmaticException, which is derived from the System.Exception. Now the question is, may I use ArithmeticException in the catch block? Yes. Why not? That is the beauty of polymorphism. When you do, always keep in mind that you are moving from more specialized information thrown to the Generalized one.
2. Handler for Multiple Exceptions
A code placed in the try block can raise different kinds of exceptions. It can be say, a Divide by Zero or a Network System Access Denied or a File not exists. How do you handle all the exceptions? The answer is, you can place multiple catch blocks for a try block. When an exception is thrown, the type of that exception is examined against each catch block. When a match occurs (Even polymorph) the exception enter into the catch block and is handled.
Let me walk through the following example:
1) Make use of Exception object in the catch block
2) Using multiple catch blocks for different exception
3) The importance order of the catch blocks.
1) Program enters the main function and calls the member function StartProgram after the creating the object of type ExceptionsP2.
[STAThread]
public static void Main(string[] args) {
ExceptionsP2 start = new ExceptionsP2();
start.StartProgram();
}
2) The StartProgram function makes a call to Calculate function. And this call is placed in the try block as it is expected that there be some arithmetic exception and possibly a Divide by Zero exception. Two catch blocks are placed for the try block of code. One is DivideByZeroException and other one is System.Exception. Inside each catch block, the exception object caught was used to display the Exception message, and function call stack of where the exception raised. Below is the code:
//001: Function that Handles the Exception
public void StartProgram() {
Console.WriteLine("Calling the Function Calculate");
try
{
Calculate();
}
catch (DivideByZeroException Ex)
{
Console.WriteLine("Divide By Zero. Look at the Call stack for More information");
Console.WriteLine("Packed Message: " + Ex.Message );
Console.WriteLine("Thrown By: " + Ex.TargetSite );
Console.Write("Call Stack: " + Ex.StackTrace );
}
catch (Exception Ex)
{
Console.WriteLine("General Exception Occurred");
Console.WriteLine("Packed Message: " + Ex.Message );
Console.Write("Call Stack: " + Ex.StackTrace );
}
}
3) The Calculate function is just an intermediate function that calls Divide. Note how the stack rewind and exception bubbling is happening. Below is the function, which makes a call to Divide, and does not have any Exception handler code:
//002: An intermediate function, just for Demo Purpose
public void Calculate() {
Console.WriteLine("Calling Divide Function ");
Divide();
}
4) The Divide function tries to divide a number by zero. The .Net environment detects the situation and raises the exception for us. Note there is no throw statement here. In my previous examples (Actually in the previous part) I forced the system to throw an exception for demonstration purposes. We usually use the throw statement for Custom defined exceptions. The .Net environment is smart enough to detect the exception at the right time and raise it. Below is the code for divide:
//003: The Divide function which actually raises an Exception
public void Divide() {
int x = 10;
int y = 0;
y = x / y;
}
3. Closing notes
The DivideByZeroException thrown in the Divide function is caught by the StartProgram function. Then the exception object is matched against the first catch block. As there is a match the exception enters that catch block.
What happens if System.Exception catch block is before the DivideByZeroException? We do enter the System.Exception catch block even though a more perfect match exists. Because the exception caught is matched from top to bottom. As the System.Exception is on the top (that is; BeforeDivideByZero) and the caught Exception DivideByZeroException is polymorphically an System.Exception the execution control just enters the System.Exception catch Block.
So always keep in Mind to place the more specific catch statement first and move down with more generalized exceptions. Look at the code below how a smart developer placed his catch block based on what his Team Lead told.
Lead: "The code block may raise a DivideByZeroException or Any ArithmeticException. It is possible to have FileNotFound Exception also. These are the possibilities of exception I am seeing when I am reviewing your code. But, for safety try to handle all exceptions in the world and it is OK if it not more specific". That all, the Lead gone to a meeting J
Forget what meeting he is going for, see how the developer placed his catch block:
try
{
// The set of code and function here
// reviewed by an Experienced lead.
}
catch (System.FileNotFoundException Ex) {
//File Not Found Exception is Different from Divide by zero.
//Look at the Inheritance hierarchy in MSDN for FileNotFoundException
//and DivideByZeroException.
//So I don't care Which one First, FileNotFond or DivideByZero
}
catch( System.DivideByZeroException Ex) {
//Divide by Zero Exception. Need More Specialized care
}
catch (System.ArithmeticException Ex) {
// For any ArithmaticException except DivideByZero. Because I already handled it
// before this catch statement
}
catch(System.Exception Ex) {
//I am not expecting that this would Occur. As per my Lead
//I placed it for safe to handle any Exception in the world
// That derived from Exception.
}
finally
{
//Clean-up code
}
Look at the comments and I hope it is self-explanatory.
See you all, I hope this article and the Previous part explained for you something about Exception Handling in C#.