|
Exception Handling in C# : Part 1
|
Excpetions are unforeseen errors that ocuur while your program is running. When an excpetion occurs and if the exception is not handled, end users receive an error message which does not make any sense to them. Excpetions should always be handled and meaningful error messages should be provided to the end user.
Let us understand exception handling with an example. Let us write a simple program
which accepts 2 numbers from the end user, divides the numbers and provides the
result to the user. |
|
using
System;
public
class MainClass
{
public
static void Main()
{
Console.WriteLine("Please enter your first number");
int FirstNumber = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Please enter your second number");
int SecondNumber = Convert.ToInt32(Console.ReadLine());
double Result = FirstNumber / SecondNumber;
Console.WriteLine("Result = " + Result);
}
}
|
There is nothing wrong with the above program. The program will continue to work
without any issues as long as the user enters a valid input.If the end user enters
any of the following input the program can raise an exception and break.
- If the user enters 0 as the second number, the program will break. We cannot divide a number by zero. In mathematics dividing a number by zero will result into infinity. Hence DivideByZero exception is raised which is not handled in our example and the program terminates with an error.
- If the User enters text instead of integers, the program will break raising an invalid format exception. This is because in our program we are reading the user input from Console and trying to convert the entered input into an integer. We cannot convert text like "One" to integer leading to InvalidFormatException which is not handled in our example and the program terminates with an error.
- If the user enters a very big number. For example a number like 545587855648687887745 is too big for a variable of type integer. In our example FirstNumber is of type integer and cannot hold this number. It overflows. Hence OverFlowException is raised which is not handled in our example and the program terminates with an error.
To handle exceptions and provide users with meaningful and useful error messages we can use exception handling in C# with try/catch blocks. The above program is rewritten using try/catch blocks as shown below.
|
|
using
System;
public
class MainClass
{
public
static void Main()
{
Console.WriteLine("Please enter your first number");
try
{
int FirstNumber = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Please
enter your second number");
int SecondNumber = Convert.ToInt32(Console.ReadLine());
double Result = FirstNumber / SecondNumber;
Console.WriteLine("Result
= " + Result);
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
|
- Run the above program and enter "One" for the FirstNumber and press enter.
- When we press enter key, the program reads the user input from the screen and tries to convert "One" to integer which will raise an exception.
- Once the exception is raised the control will be immediately transfered to the catch block. In the catch block we are handling the exception and witing the exception message to the screen using
Console.WriteLine(ex.Message);
- When an exception occurs, an object of type System.Exception is thrown. Catch block is capable of catching and handling this object. If the catch block is not available to handle the raised exception, the program will terminate with an error.
- In our example, ex is an instance of exception class. We are using the Message property of the exception object, to let the user know about the error message. The exception object has other properties like ex.StackTrace and methods like ex.ToString() which can give additional information about the exception that has occured. For a clear understanding of properties
please read properties in C# article
and for methods
please read methods in C# article.
-
Although this example is using exception handling, it is not coded in the right way. All the excpetions are caught by a single top level Exception class. If you want to provide users with an error message specifying what exactly went wrong, look at the example below.
|
|
using
System;
public
class MainClass
{
public
static void Main()
{
Console.WriteLine("Please enter your first number");
try
{
int FirstNumber = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Please
enter your second number");
int SecondNumber = Convert.ToInt32(Console.ReadLine());
double Result = FirstNumber / SecondNumber;
Console.WriteLine("Result
= " + Result);
}
catch (FormatException)
{
Console.WriteLine("Enter
only numbers");
}
catch (OverflowException)
{
Console.WriteLine("Enter numbers between " +
Int32.MinValue.ToString() + " and "
+ Int32.MaxValue.ToString());
}
catch (DivideByZeroException)
{
Console.WriteLine("You cannot
divide a number by 0, Please enter a non zero Second Number");
}
catch (Exception Ex)
{
Console.WriteLine(Ex.Message);
}
Console.WriteLine("Bye!!!!!");
}
}
|
- The above example demonstrates proper usage of excpetion handling. A single try block can have multiple catch blocks. Each catch block handles a specific type of exception. In the end we have the generic exception block, which will handle an exception that is not handled by any of the above catch blocks.
- If the end user enters a string or special characters which cannot be converted to an integer then a FormatException is raised. Our program handles this exception using the below catch block
catch (FormatException)
{
Console.WriteLine("Enter only numbers");
}
- If the end user enters 0 as the second number, DivideVyZero exception is handled
by
catch (DivideByZeroException)
{
Console.WriteLine("You cannot divide a number by 0, Please
enter a non zero Second Number");
}
- If the end user enters a large number, OverFlowException occurs and it is handled
by
catch (OverflowException)
{
Console.WriteLine("Enter numbers between " + Int32.MinValue.ToString()
+ " and " + Int32.MaxValue.ToString());
}
- If any other exception occurs we have the generic Execption block which can handle
that excpetion.
catch (Exception Ex)
{
Console.WriteLine(Ex.Message);
}
- Always, the most specific exception blocks should be on top and the general exception
block should be in the end. including the general Exception block as the first catch
block and then the specific exception blocks will result in a compile time error
"previous catch clause already catches all exceptions of this or of a super type
('System.Exception')"
- When an exception occurs, the control will be immediately transfered to the suitable
catch block which is capable of handling the exception. The code in that specific
catch block will be executed. No other catch blocks will be executed. The control
will be transfered to the first statement at the end of the last catch block. In
our example if a FormatExcption is raised, FormatExcption catch block code will
be executed. After that the control the following line will be executed without
executing code in any other catch block.
Console.WriteLine("Bye!!!!!");
|
|
Throwing exceptions
|
|
In C# we can use the throw keyword to raise exceptions.If you look at the program below, in the first catch block we are raising an exception using the throw keyword. Will this new exception be handled by the second catch block. The answer is No.
|
|
using
System;
public
class MainClass
{
public
static void Main()
{
Console.WriteLine("Please enter your first number");
try
{
int FirstNumber = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Please enter your second number");
int SecondNumber = Convert.ToInt32(Console.ReadLine());
double Result = FirstNumber / SecondNumber;
Console.WriteLine("Result
= " + Result);
}
catch (FormatException)
{
Console.WriteLine("Enter
only numbers");
throw new
Exception();
}
catch (Exception Ex)
{
Console.WriteLine(Ex.Message);
}
}
}
|
|
If you intend to catch an exception. The code that raises that exception must be inside a try block as shown in the rewritten example below. This type of question is commonly asked in your interview.
The example below proves that you can have a try block inside a catch block.
|
|
using
System;
public
class MainClass
{
public
static void Main()
{
Console.WriteLine("Please enter your first number");
try
{
int FirstNumber = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Please
enter your second number");
int SecondNumber = Convert.ToInt32(Console.ReadLine());
double Result = FirstNumber / SecondNumber;
Console.WriteLine("Result
= " + Result);
}
catch (FormatException)
{
Console.WriteLine("Enter
only numbers");
try
{
throw new Exception();
}
catch (Exception
Ex)
{
Console.WriteLine(Ex.Message);
}
}
catch (Exception Ex)
{
Console.WriteLine(Ex.Message);
}
}
}
|
|
Further Reading
|
|
|
|
Other related articles
|
|
|
Njoy Programming
ByPrasad Cherukuri
|