An exception is a problem that arises during the execution of a program. A C# 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. C# exception handling is built upon four keywords: try, catch, finally and throw.
try: A try block identifies a block of code for which particular exceptions will be activated. It's followed by one or more catch blocks.
catch: A program catches an exception with an exception handler at the place in a program where you want to handle the problem. The catch keyword indicates the catching of an exception.
finally: The finally block is used to execute a given set of statements, whether an exception is thrown or not thrown. For example, if you open a file, it must be closed whether an exception is raised or not.
throw: A program throws an exception when a problem shows up. This is done using a throw keyword.
Syntax
Assuming a block will raise and exception, a method catches an exception using a combination of the try and catch keywords. A try/catch block is placed around the code that might generate an exception. Code within a try/catch block is referred to as protected code, and the syntax for using try/catch looks like the following:
try
{
// statements causing exception
}
catch( ExceptionName e1 )
{
// error handling code
}
catch( ExceptionName e2 )
{
// error handling code
}
catch( ExceptionName eN )
{
// error handling code
}
finally
{
// statements to be executed
}
You can list down multiple catch statements to catch different type of exceptions in case your try block raises more than one exception in different situations.
Exception Classes in C#
C# exceptions are represented by classes. The exception classes in C# are mainly directly or indirectly derived from the System.Exception class. Some of the exception classes derived from the System.Exception class are the System.ApplicationException and System.SystemException classes.
The System.ApplicationException class supports exceptions generated by application programs. So the exceptions defined by the programmers should derive from this class.
The System.SystemException class is the base class for all predefined system exception.
The following table provides some of the predefined exception classes derived from the Sytem.SystemException class:
Exception Class Description
System.IO.IOException Handles I/O errors.
System.IndexOutOfRangeException Handles errors generated when a method refers to an array index out of range.
System.ArrayTypeMismatchException Handles errors generated when type is mismatched with the array type.
System.NullReferenceException Handles errors generated from deferencing a null object.
System.DivideByZeroException Handles errors generated from dividing a dividend with zero.
System.InvalidCastException Handles errors generated during typecasting.
System.OutOfMemoryException Handles errors generated from insufficient free memory.
System.StackOverflowException Handles errors generated from stack overflow.
Handling Exceptions
C# provides a structured solution to the exception handling problems in the form of try and catch blocks. Using these blocks the core program statements are separated from the error-handling statements.
These error handling blocks are implemented using the try, catch and finally keywords. Following is an example of throwing an exception when dividing by zero condition occurs:
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();
}
}
}
When the above code is compiled and executed, it produces the following result:
Exception caught: System.DivideByZeroException: Attempted to divide by zero.
at ...
Result: 0
Creating User-Defined Exceptions
You can also define your own exception. User-defined exception classes are derived from the ApplicationException class. The following example demonstrates this:
using System;
namespace UserDefinedException
{
class TestTemperature
{
static void Main(string[] args)
{
Temperature temp = new Temperature();
try
{
temp.showTemp();
}
catch(TempIsZeroException e)
{
Console.WriteLine("TempIsZeroException: {0}", e.Message);
}
Console.ReadKey();
}
}
}
public class TempIsZeroException: ApplicationException
{
public TempIsZeroException(string message): base(message)
{
}
}
public class Temperature
{
int temperature = 0;
public void showTemp()
{
if(temperature == 0)
{
throw (new TempIsZeroException("Zero Temperature found"));
}
else
{
Console.WriteLine("Temperature: {0}", temperature);
}
}
}
When the above code is compiled and executed, it produces the following result:
TempIsZeroException: Zero Temperature found
Throwing Objects
You can throw an object if it is either directly or indirectly derived from the System.Exception class. You can use a throw statement in the catch block to throw the present object as:
Catch(Exception e)
{
...
Throw e
}
**********************************************************************************
The InnerException property returns the Exception instance that caused the current exception.
To look at the inner exception, you have to make this program cuase an exception fail. To do that you have 3 options
1. Enter a Character instead of a number (Causes Format Exception)
2. Or Enter a very big number that an interger cannot hold (Causes Over Flow Exception)
3. Or Enter Zero for Second Number (Causes Divide By Zero Exception)
using System;
using System.IO;
class ExceptionHandling
{
public static void Main()
{
try
{
try
{
Console.WriteLine("Enter First Number");
int FN = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Enter Second Number");
int SN = Convert.ToInt32(Console.ReadLine());
int Result = FN / SN;
Console.WriteLine("Result = {0}", Result);
}
catch (Exception ex)
{
string filePath = @"C:\Sample Files\Log.txt";
if (File.Exists(filePath))
{
StreamWriter sw = new StreamWriter(filePath);
sw.Write(ex.GetType().Name + ex.Message + ex.StackTrace);
sw.Close();
Console.WriteLine("There is a problem! Plese try later");
}
else
{
//To retain the original exception pass it as a parameter
//to the constructor, of the current exception
throw new FileNotFoundException(filePath + " Does not Exist", ex);
}
}
}
catch (Exception ex)
{
//ex.Message will give the current exception message
Console.WriteLine("Current or Outer Exception = " + ex.Message);
//Check if inner exception is not null before accessing Message property
//else, you may get Null Reference Excception
if(ex.InnerException != null)
{
Console.WriteLine("Inner Exception = ", ex.InnerException.Message);
}
}
}
}
**********************
Syntax
Property Value
Implements
Remarks
Exceptions provide a way to transfer control from one part of a program to another. C# exception handling is built upon four keywords: try, catch, finally and throw.
try: A try block identifies a block of code for which particular exceptions will be activated. It's followed by one or more catch blocks.
catch: A program catches an exception with an exception handler at the place in a program where you want to handle the problem. The catch keyword indicates the catching of an exception.
finally: The finally block is used to execute a given set of statements, whether an exception is thrown or not thrown. For example, if you open a file, it must be closed whether an exception is raised or not.
throw: A program throws an exception when a problem shows up. This is done using a throw keyword.
Syntax
Assuming a block will raise and exception, a method catches an exception using a combination of the try and catch keywords. A try/catch block is placed around the code that might generate an exception. Code within a try/catch block is referred to as protected code, and the syntax for using try/catch looks like the following:
try
{
// statements causing exception
}
catch( ExceptionName e1 )
{
// error handling code
}
catch( ExceptionName e2 )
{
// error handling code
}
catch( ExceptionName eN )
{
// error handling code
}
finally
{
// statements to be executed
}
You can list down multiple catch statements to catch different type of exceptions in case your try block raises more than one exception in different situations.
Exception Classes in C#
C# exceptions are represented by classes. The exception classes in C# are mainly directly or indirectly derived from the System.Exception class. Some of the exception classes derived from the System.Exception class are the System.ApplicationException and System.SystemException classes.
The System.ApplicationException class supports exceptions generated by application programs. So the exceptions defined by the programmers should derive from this class.
The System.SystemException class is the base class for all predefined system exception.
The following table provides some of the predefined exception classes derived from the Sytem.SystemException class:
Exception Class Description
System.IO.IOException Handles I/O errors.
System.IndexOutOfRangeException Handles errors generated when a method refers to an array index out of range.
System.ArrayTypeMismatchException Handles errors generated when type is mismatched with the array type.
System.NullReferenceException Handles errors generated from deferencing a null object.
System.DivideByZeroException Handles errors generated from dividing a dividend with zero.
System.InvalidCastException Handles errors generated during typecasting.
System.OutOfMemoryException Handles errors generated from insufficient free memory.
System.StackOverflowException Handles errors generated from stack overflow.
Handling Exceptions
C# provides a structured solution to the exception handling problems in the form of try and catch blocks. Using these blocks the core program statements are separated from the error-handling statements.
These error handling blocks are implemented using the try, catch and finally keywords. Following is an example of throwing an exception when dividing by zero condition occurs:
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();
}
}
}
When the above code is compiled and executed, it produces the following result:
Exception caught: System.DivideByZeroException: Attempted to divide by zero.
at ...
Result: 0
Creating User-Defined Exceptions
You can also define your own exception. User-defined exception classes are derived from the ApplicationException class. The following example demonstrates this:
using System;
namespace UserDefinedException
{
class TestTemperature
{
static void Main(string[] args)
{
Temperature temp = new Temperature();
try
{
temp.showTemp();
}
catch(TempIsZeroException e)
{
Console.WriteLine("TempIsZeroException: {0}", e.Message);
}
Console.ReadKey();
}
}
}
public class TempIsZeroException: ApplicationException
{
public TempIsZeroException(string message): base(message)
{
}
}
public class Temperature
{
int temperature = 0;
public void showTemp()
{
if(temperature == 0)
{
throw (new TempIsZeroException("Zero Temperature found"));
}
else
{
Console.WriteLine("Temperature: {0}", temperature);
}
}
}
When the above code is compiled and executed, it produces the following result:
TempIsZeroException: Zero Temperature found
Throwing Objects
You can throw an object if it is either directly or indirectly derived from the System.Exception class. You can use a throw statement in the catch block to throw the present object as:
Catch(Exception e)
{
...
Throw e
}
[SerializableAttribute]
[ComVisibleAttribute(true)]
[ClassInterfaceAttribute(ClassInterfaceType.None)]
public class Exception : ISerializable, _Exception
The Exception type exposes the following members.
Show:
Name
|
Description
|
|
Initializes
a new instance of the Exception class.
|
||
Initializes
a new instance of the Exception class
with a specified error message.
|
||
Initializes
a new instance of the Exception class
with serialized data.
|
||
Initializes
a new instance of the Exception class
with a specified error message and a reference to the inner exception that is
the cause of this exception.
|
Show:
Name
|
Description
|
|
Gets a
collection of key/value pairs that provide additional user-defined
information about the exception.
|
||
Gets or
sets a link to the help file associated with this exception.
|
||
Gets or
sets HRESULT, a coded numerical value that is assigned to a specific exception.
|
||
Gets the Exception instance that caused the current
exception.
|
||
Gets a
message that describes the current exception.
|
||
Gets or
sets the name of the application or the object that causes the error.
|
||
Gets a
string representation of the immediate frames on the call stack.
|
||
Gets the
method that throws the current exception.
|
Show:
Name
|
Description
|
|
Determines
whether the specified object is equal to the current object. (Inherited from Object.)
|
||
Allows an
object to try to free resources and perform other cleanup operations before
it is reclaimed by garbage collection. (Inherited
from Object.)
|
System.Object
System.Exception
System.SystemException
System.IO.IOException
System.IO.FileNotFoundException
System.Exception
System.SystemException
System.IO.IOException
System.IO.FileNotFoundException
public class FileNotFoundException : IOException
Show:
Name
|
Description
|
|
Gets a
collection of key/value pairs that provide additional user-defined
information about the exception. (Inherited
fromException.)
|
||
Gets the
name of the file that cannot be found.
|
||
Gets the
log file that describes why loading of an assembly failed.
|
||
Gets or
sets a link to the help file associated with this exception. (Inherited from Exception.)
|
||
Gets or
sets HRESULT, a coded numerical value that is assigned to a specific
exception. (Inherited from Exception.)
|
||
Gets the
error message that explains the reason for the exception. (Overrides Exception.Message.)
In XNA Framework 3.0, this member is inherited from Exception.Message. |
||
Gets or
sets the name of the application or the object that causes the error. (Inherited from Exception.)
|
||
Gets a
string representation of the immediate frames on the call stack. (Inherited from Exception.)
|
||
Gets the
method that throws the current exception. (Inherited
from Exception.)
|
Exception class properties
The Exception class includes a number of properties
that help identify the code location, the type, the help file, and the reason
for the exception: StackTrace,InnerException, Message, HelpLink, HResult, Source, TargetSite, and Data.
When
a causal relationship exists between two or more exceptions, the InnerException property maintains this information.
The outer exception is thrown in response to this inner exception. The code
that handles the outer exception can use the information from the earlier inner
exception to handle the error more appropriately. Supplementary information
about the exception can be stored as a collection of key/value pairs in the Data property.
**********************************************************************************
Reference
Exception Handling for C# Beginners
1. Introduction to Exceptions
An
Exception
is an object delivered by the Exception
class. This Exception
class is exposed by theSystem.Exception
namespace. Exception
s are used to avoid system failure in an unexpected manner. Exception
handles the failure situation that may arise. All the exception
s in the .NET Framework are derived from theSystem.Exception
class.
To understand
exception
, we need to know two basic things:- Somebody sees a failure situation that happened and throws an exception by packing the valid information.
- Somebody who knows that a failure may happen catches the exception thrown. We call it
Exception
Handler.
Below is a simple example, which shows what happens when an
Exception
is not handled:class ExceptionsEx
{
//001: Start the Program Execution.
public void StartProgram()
{
Console.WriteLine("Making Call to F1() " );
F1();
Console.WriteLine("Successfully returned from F1() " );
}
//002: Set of Function that calls each other
public void F1()
{
Console.WriteLine("Making Call to F2() " );
throw new System.Exception();
F2();
Console.WriteLine("Successfully returned from F2() " );
}
public void F2()
{
Console.WriteLine("Inside F2 " );
}
//Client 001: Program Entry
[STAThread]
static void Main(string[] args)
{
//Create the Object and start the Execution
ExceptionsEx app = new ExceptionsEx();
app.StartProgram();
}
}
In the above code, look at the function F1 that throws an
Exception
. But, there is no handler to deal with the thrownexception
. This situation is called an Un-Handled exception
situation. When you execute the code, you get an unhandled exception
dialog.
The above dialog is shown in debug mode, so you may get a chance to break the execution to see where the exception is thrown (or) continue ignoring the
exception
(not advisable).
In release mode, you will get un-handled
Exception
in the form of Application crash.
So, how do we avoid Un-Handled
Exception
? Simple, handle it.2. Handling Exception
To handle the exception, we need to place the code within the
try
block. When an exception occurs inside the try
block, the control looks for the catch
block and raises an exception that is handled in the catch
block. Below is the simple skeleton for the try
and catch
block:try
{
//Some Code that may expected to raise an exception
}
catch
{
//Raised exception Handled here
}
The above skeleton handles any
exception
. But, the main disadvantage is that we don’t know what exception
is raised and who raised the exception
. Below is the example that handles the Exception
raised by the function F1 and avoids the crash:class ExceptionsEx
{
//001: Start the Program Execution.
public void StartProgram()
{
Console.WriteLine("Making Call to F1() " );
try
{
F1();
}
catch
{
Console.WriteLine("Some Exception Occurred.
I don't know what Exception it is and where it Occurred. Sorry!");
}
Console.WriteLine("Successfully returned from F1() " );
}
//002: Set of Function that calls each other
public void F1()
{
Console.WriteLine("Making Call to F2() " );
throw new System.Exception();
Console.WriteLine("Successfully returned from F2() " );
}
//Client 001: Program Entry
[STAThread]
static void Main(string[] args)
{
//Create the Object and start the Execution
ExceptionsEx app = new ExceptionsEx();
app.StartProgram();
}
}
3. Exception Bubbling
In the above example, we saw that
Exception
is handled in the catch
block. But, the function call order is simple (Call Stack) that is; StartProgram
calls the function F1 and F1 raised exception
is handled in the catch
block of theStartProgram
.
Imagine the situation what happens if there are multiple nested function calls, and
exception
occurred in the fourth or fifth nested call. Look at the picture below:F1()
: CallsF2
within thetry
block and handles the exception incatch
blockF2()
: Makes a call to the functionF3
. But it neither wraps the call forF3
in thetry
block nor has the exception handlerF3()
: Raises an Exception
Note, when the exception is thrown by the function
Below is the example that demonstrates the
F3
, even though the caller is F2
, as there is no catch
handler, the execution comes out of F2
and enters the catch
block of F1
. Travelling back from F3
->F2
->F1
is known as Stack Unwind. And exception occurred in F3
is handled in F1
even when there is no handler at F2
is known as Exception
Bubbling.Below is the example that demonstrates the
Exception
Bubbling:using System;
namespace ExceptionHandling
{
class ExceptionsEx
{
//001: Start the Program Execution.
public void StartProgram()
{
Console.WriteLine("Making Call to F1() " );
try
{
F1();
}
catch
{
Console.WriteLine("Some Exception Occurred.
I don't know what Exception it is and where it Occurred. Sorry!");
}
Console.WriteLine("Successfully returned from F1() " );
}
//002: Set of Function that calls each other
public void F1()
{
Console.WriteLine("Making Call to F2() " );
F2();
Console.WriteLine("Successfully returned from F2() " );
}
public void F2()
{
Console.WriteLine("Making Call to F2() " );
F3();
Console.WriteLine("Successfully returned from F2() " );
}
public void F3()
{
Console.WriteLine("Inside F3 " );
throw new System.Exception();
}
//Client 001: Program Entry
[STAThread]
static void Main(string[] args)
{
//Create the Object and start the Execution
ExceptionsEx app = new ExceptionsEx();
app.StartProgram();
}
}
}
4. The Importance of Finally Block
In the above example, we saw that when an
exception
occurs, we directly jump back on the call stack and travel back searching for the catch
handler. What about the piece of code that comes next to the exception raising code? If we do releasing resource and releasing the heap memory in the next couple of statements, that will not get reached. Right?Finally
block is the solution for this. Now look at the improved exception
-handling skeleton below:try
{
}
catch
{
}
finally
{
}
Whatever happens inside the
try
block, it is guaranteed that finally
block gets executed. Hence, all resource releases should be in the finally
block. Have a look at the below picture:Exception
raised at function F3
is handled in the function F2
. Look at the try
block, I marked two blocks of code before exception
and code after exception
. It is obvious that when an exception
raised, the set of code inside the code after exception is never executed. If resources are allocated in code before exception and the allocated resources are released in code after exception, we do have a resource leak for each exception
occurred. Also, think about business logic that needs to revert back apart from the resource leak. This is why finally
block is introduced.
Whether an
Exception
occurs or not, the code inside finally
block always gets executed. So you can keep all the cleaning code inside the finally
block. The attached sample solution explains the above situation. Put a break point in the very first statement of the function public void StartProgram()
and examine the situation explained above. Note, the usage of try
block with only finally
and without catch
in function F2
. Think about it.5. What is Exception Class?
This class is provided by .NET Framework to handle any
exception
that occurred. The Exception
class is the base class for all other Exception
class provided by .NET Framework.
The exception object has some important properties. Some of then are given below:
Property | Usage |
Message | Gives detailed information about the message |
StackTrace | Gives the function stack to show where exception is thrown |
Targetsite | Shows which method throws the exception |
In the previous example, we only used the
catch
block and missed all the above said information. The exception
object is thrown by the piece of code, which raises an Exception
and the handler code catches that Exception
object and makes use of the information packed in it. Consider the below example: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 from where the object that is used in the
catch
block is coming from. Hope, now you 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 theSystem.Exception
. Now the question is, May I use ArithmaticException
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.6. Handler for Multiple Exceptions
A code placed in the
try
block can raise different kinds of exception. 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 multiplecatch
blocks for a try
block. When an exception is thrown, type of that exception is examined against each catch
block. When a match occurs (even polymorph), the exception
enters into the catch
block and gets handled.
Let me walk through an example, which will explain the following to you:
- Make use of
Exception
object in thecatch
block - Using multiple
catch
blocks for differentexception
s - The importance order of the
catch
blocks
1) Program enters the main function and calls the member function
StartProgram
after creating the object of typeExceptionsP2
.[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 eachcatch
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 is just an intermediate function which makes a call to
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 my demonstration purpose. We usually use the throw
statement for Custom defined exceptions. The .NET environment is smart enough to detect the exception at 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;
}
7. Closing Notes
The
DivideByZeroException
thrown in the Divide
function is caught by the StartProgram
function. Then theexception
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 theSystem.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; Before DivideByZero
) and the caught Exception DivideByZeroException
is polymorphically a System.Exception
the execution control just enters the System.Exception catch
block.
So always keep in mind to place more specific
catch
statement first and move down with more GeneralizedException
s. 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 haveFileNotFound Exception
also. These are the possibilities of Exception
I am seeing when I am reviewing your code. But, for safety, try to handle all exception
s in the world and it is OK if it is not more specific”.
That's all, the Lead went to a meeting.
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
}
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; Before DivideByZero) and the caught Exception DivideByZeroException is polymorphically a System.Exception the execution control just enters the System.Exception catch block."
But it is not possible because we can not define System.Exception catch block before the DivideByZeroException catch block otherwise it will generate an error "A previous catch clause already catches all exceptions of this or of super type".
But it is not possible because we can not define System.Exception catch block before the DivideByZeroException catch block otherwise it will generate an error "A previous catch clause already catches all exceptions of this or of super type".
cccccc
using System;
namespace Exception_hand
{
class Class1
{
public void somemethod()
{
try
{
System.IO.FileNotFoundException q = new System.IO.FileNotFoundException("amit","Myfilenamenotfound");
//throw new System.IO.FileNotFoundException();
//OR
throw q;
}
//catch (System.IO.FileNotFoundException ex)
//{
// Console.WriteLine(ex.Message + " " + ex.FileName);
// Console.ReadLine();
//}
//catch (System.IO.IOException)
//{
//}
catch (System.InvalidCastException)
{
}
catch (System.ArgumentException)
{
}
catch (Exception ex)
{
Console.WriteLine(ex.Message +" "+ex.Source);
Console.ReadLine();
}
}
public static void Main(string[] args)
{
Class1 a = new Class1();
a.somemethod();
}
}
}
namespace Exception_hand
{
class Class1
{
public void somemethod()
{
try
{
System.IO.FileNotFoundException q = new System.IO.FileNotFoundException("amit","Myfilenamenotfound");
//throw new System.IO.FileNotFoundException();
//OR
throw q;
}
//catch (System.IO.FileNotFoundException ex)
//{
// Console.WriteLine(ex.Message + " " + ex.FileName);
// Console.ReadLine();
//}
//catch (System.IO.IOException)
//{
//}
catch (System.InvalidCastException)
{
}
catch (System.ArgumentException)
{
}
catch (Exception ex)
{
Console.WriteLine(ex.Message +" "+ex.Source);
Console.ReadLine();
}
}
public static void Main(string[] args)
{
Class1 a = new Class1();
a.somemethod();
}
}
}
In above Example See the beauty of Polymorphism. all exception class derived from Exception class, So Exception class reference obj can hold any of the derived class instance object. However (reference obj of exception ) it can call only the property that are of BASE type.
Un-comment above code you will get the file name also.
Inner Exception allow us to track Original Exception.
Part 40 - C# Tutorial - Exception Handling
Part 41 Inner-exceptions
The InnerException is a property of an exception. When there are series of exceptions, the most current exception can obtain the prior exception in the InnerException property.
Let us say we have an exception inside a try block throwing an ArgumentException and the catch clause catches it and writes it to a file. However, if the file path is not found, FileNotFoundException is thrown. Let's say that the outside try block catches this exception, but how about the actual ArgumentException that was thrown? Is it lost? No, the InnerException property contains the actual exception. This is the reason for the existence of an InnerException property for any exception.
Inner Exception allow us to track Original Exception.
Part 40 - C# Tutorial - Exception Handling
Part 41 Inner-exceptions
The InnerException is a property of an exception. When there are series of exceptions, the most current exception can obtain the prior exception in the InnerException property.
Let us say we have an exception inside a try block throwing an ArgumentException and the catch clause catches it and writes it to a file. However, if the file path is not found, FileNotFoundException is thrown. Let's say that the outside try block catches this exception, but how about the actual ArgumentException that was thrown? Is it lost? No, the InnerException property contains the actual exception. This is the reason for the existence of an InnerException property for any exception.
The InnerException property returns the Exception instance that caused the current exception.
To look at the inner exception, you have to make this program cuase an exception fail. To do that you have 3 options
1. Enter a Character instead of a number (Causes Format Exception)
2. Or Enter a very big number that an interger cannot hold (Causes Over Flow Exception)
3. Or Enter Zero for Second Number (Causes Divide By Zero Exception)
using System;
using System.IO;
class ExceptionHandling
{
public static void Main()
{
try
{
try
{
Console.WriteLine("Enter First Number");
int FN = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Enter Second Number");
int SN = Convert.ToInt32(Console.ReadLine());
int Result = FN / SN;
Console.WriteLine("Result = {0}", Result);
}
catch (Exception ex)
{
string filePath = @"C:\Sample Files\Log.txt";
if (File.Exists(filePath))
{
StreamWriter sw = new StreamWriter(filePath);
sw.Write(ex.GetType().Name + ex.Message + ex.StackTrace);
sw.Close();
Console.WriteLine("There is a problem! Plese try later");
}
else
{
//To retain the original exception pass it as a parameter
//to the constructor, of the current exception
throw new FileNotFoundException(filePath + " Does not Exist", ex);
}
}
}
catch (Exception ex)
{
//ex.Message will give the current exception message
Console.WriteLine("Current or Outer Exception = " + ex.Message);
//Check if inner exception is not null before accessing Message property
//else, you may get Null Reference Excception
if(ex.InnerException != null)
{
Console.WriteLine("Inner Exception = ", ex.InnerException.Message);
}
}
}
}
**********************
Exception.InnerException
Property
Syntax
C#
public Exception InnerException { get; }
Property Value
Type: System.Exception
An instance of Exception that describes the error that caused the current exception. The InnerException property returns the same value as was passed into the constructor, or a null reference (Nothing in Visual Basic) if the inner exception value was not supplied to the constructor. This property is read-only.
An instance of Exception that describes the error that caused the current exception. The InnerException property returns the same value as was passed into the constructor, or a null reference (Nothing in Visual Basic) if the inner exception value was not supplied to the constructor. This property is read-only.
Implements
Remarks
When
an exception X is
thrown as a direct result of a previous exception Y,
the InnerException property of X should contain a reference to Y.
Use
the InnerException property to obtain the set of
exceptions that led to the current exception.
You
can create a new exception that catches an earlier exception. The code that
handles the second exception can make use of the additional information from
the earlier exception to handle the error more appropriately.
Suppose
that there is a function that reads a file and formats the data from that file.
In this example, as the code tries to read the file, an IOException is
thrown. The function catches the IOException and
throws a FileNotFoundException. The IOException could
be saved in the InnerException property
of theFileNotFoundException,
enabling the code that catches the FileNotFoundException to examine what causes the initial
error.
The InnerException property, which holds a reference to the
inner exception, is set upon initialization of the exception object.
public Exception InnerException { get; }
InnerException is Type of
Exception which is base class of any Exception class in .net framework. See
below
using System;
namespace KudVenkatCsharp
{
public class MyAppException : ApplicationException
{
public Exception
currentexception{get;set;}
public MyAppException(String message)
{ }//Here in below constructer we passed the
Excetion inner that means it will initilize the Base class Innerexcetion
property. So If you want to keep track on the previous exception in the current
excetion, So pass Exception instance in the constructer of current exception.
previous excetion you will get as the Base excetion type since you send that
excetion to base excetion class. You can get the inner excetion in the parent
child relationship only.
//Why ? /Two excption occured one you hold as
the Derived class excetion and other one you pass to the Base class Exception
which can hold any exception that is why we shud derive our class from
ApplicationException or Excetion, by default .net framework excetion inherited
from Exception class.
public MyAppException(String message, Exception inner) : base(message,inner) {
}
public void ThrowInner()
{
throw new MyAppException("Inner
exception. First Excetion .ThrowInner()");
}
public void CatchInner()
{
try
{
this.ThrowInner();
}
catch (Exception e)//this ( MyAppException) exception we
pass to base class Exception class to hold its reference.
{
throw new MyAppException("Current
Exception CatchInner()", e);//
}
}
}
public class Test
{
public static void Main()
{
MyAppException testInstance = new MyAppException("Exception");
try
{
testInstance.CatchInner();
}
catch (Exception e)
{
testInstance.currentexception =
e;
Console.WriteLine("Current
exception");
Console.WriteLine("******************************************");
Console.WriteLine("In Main catch
block. Caught: {0}", testInstance.currentexception.Message);
Console.WriteLine("******************************************");
Console.WriteLine("******************************************");
Console.WriteLine("current
exception stack trace Similar to throw Ex which ovverides the original stack
trace");
Console.WriteLine("******************************************");
Console.WriteLine(
testInstance.currentexception.StackTrace);//Similar to throw Ex which ovverides the
original stack trace
Console.WriteLine("******************************************");
Console.WriteLine("******************************************");
Console.WriteLine("******************************************");
Console.WriteLine("******************************************");
Console.ReadLine();
Console.WriteLine("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
Console.WriteLine("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
Console.WriteLine("Prior
exception. Inner Exception");
Console.WriteLine("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
if (e.InnerException!=null)
{
Console.WriteLine("Inner
Exception is {0}", e.InnerException);
Console.WriteLine("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
Console.WriteLine("Prior exception
stack trace");
Console.WriteLine("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
Console.WriteLine("Inner
Exception is {0}", e.StackTrace);
Console.ReadLine();
}
}
}
}
}
The InnerException is a property of an exception. When there
are series of exceptions, the most current exception can obtain the prior
exception in the InnerException property.
Let us say we have an exception inside a try block throwing an ArgumentException and the catch clause catches it and writes it to a file. However, if the file path is not found, FileNotFoundException is thrown. Let's say that the outside try block catches this exception, but how about the actual ArgumentException that was thrown? Is it lost? No, the InnerException property contains the actual exception. This is the reason for the existence of an InnerException property for any exception.
Let us say we have an exception inside a try block throwing an ArgumentException and the catch clause catches it and writes it to a file. However, if the file path is not found, FileNotFoundException is thrown. Let's say that the outside try block catches this exception, but how about the actual ArgumentException that was thrown? Is it lost? No, the InnerException property contains the actual exception. This is the reason for the existence of an InnerException property for any exception.
The following example, Listing 7.13, demonstrates the concept
of checking the inner exception.
Listing 7.13: Exception13.cs, InnerException Example
using System;
using System.IO;
public class TestInnerException
{
public static void Main()
{
try
{
try
{
throw new ArgumentException();
}
catch (ArgumentException e)
{
//make sure this path does not exist
if (File.Exists("file://Bigsky//log.txt%22)%20==%20false) == false)
{
throw new FileNotFoundException("File Not found when trying to write argument exception to the file", e);
}
}
}
catch (Exception e)
{
Console.WriteLine(String.Concat(e.StackTrace, e.Message));
if (e.InnerException != null)
{
Console.WriteLine("Inner Exception");
Console.WriteLine(String.Concat(e.InnerException.StackTrace, e.InnerException.Message));
}
}
Console.ReadLine();
}
}
Listing 7.13: Exception13.cs, InnerException Example
using System;
using System.IO;
public class TestInnerException
{
public static void Main()
{
try
{
try
{
throw new ArgumentException();
}
catch (ArgumentException e)
{
//make sure this path does not exist
if (File.Exists("file://Bigsky//log.txt%22)%20==%20false) == false)
{
throw new FileNotFoundException("File Not found when trying to write argument exception to the file", e);
}
}
}
catch (Exception e)
{
Console.WriteLine(String.Concat(e.StackTrace, e.Message));
if (e.InnerException != null)
{
Console.WriteLine("Inner Exception");
Console.WriteLine(String.Concat(e.InnerException.StackTrace, e.InnerException.Message));
}
}
Console.ReadLine();
}
}
The InnerException
property returns the Exception instance that caused the current exception.
To look at the inner exception, you have to make this program cuase an exception fail. To do that you have 3 options
1. Enter a Character instead of a number (Causes Format Exception)
2. Or Enter a very big number that an interger cannot hold (Causes Over Flow Exception)
3. Or Enter Zero for Second Number (Causes Divide By Zero Exception)
To look at the inner exception, you have to make this program cuase an exception fail. To do that you have 3 options
1. Enter a Character instead of a number (Causes Format Exception)
2. Or Enter a very big number that an interger cannot hold (Causes Over Flow Exception)
3. Or Enter Zero for Second Number (Causes Divide By Zero Exception)
Part 41 - C#
Tutorial - Inner Exceptions
using System;
using System.IO;
class ExceptionHandling
{
public static void Main()
{
try
{
try
{
Console.WriteLine("Enter First Number");
int FN = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Enter Second Number");
int SN = Convert.ToInt32(Console.ReadLine());
int Result = FN / SN;
Console.WriteLine("Result = {0}", Result);
}
catch (Exception ex)
{
string filePath = @"C:\Sample Files\Log.txt";
if (File.Exists(filePath))
{
StreamWriter sw = new StreamWriter(filePath);
sw.Write(ex.GetType().Name + ex.Message + ex.StackTrace);
sw.Close();
Console.WriteLine("There is a problem! Plese try later");
}
else
{
//To retain the original exception pass it as a parameter
//to the constructor, of the current exception
throw new FileNotFoundException(filePath + " Does not Exist", ex);
}
}
}
catch (Exception ex)
{
//ex.Message will give the current exception message
Console.WriteLine("Current or Outer Exception = " + ex.Message);
//Check if inner exception is not null before accessing Message property
//else, you may get Null Reference Excception
if(ex.InnerException != null)
{
Console.WriteLine("Inner Exception = ", ex.InnerException.Message);
}
}
}
}
using System;
using System.IO;
class ExceptionHandling
{
public static void Main()
{
try
{
try
{
Console.WriteLine("Enter First Number");
int FN = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("Enter Second Number");
int SN = Convert.ToInt32(Console.ReadLine());
int Result = FN / SN;
Console.WriteLine("Result = {0}", Result);
}
catch (Exception ex)
{
string filePath = @"C:\Sample Files\Log.txt";
if (File.Exists(filePath))
{
StreamWriter sw = new StreamWriter(filePath);
sw.Write(ex.GetType().Name + ex.Message + ex.StackTrace);
sw.Close();
Console.WriteLine("There is a problem! Plese try later");
}
else
{
//To retain the original exception pass it as a parameter
//to the constructor, of the current exception
throw new FileNotFoundException(filePath + " Does not Exist", ex);
}
}
}
catch (Exception ex)
{
//ex.Message will give the current exception message
Console.WriteLine("Current or Outer Exception = " + ex.Message);
//Check if inner exception is not null before accessing Message property
//else, you may get Null Reference Excception
if(ex.InnerException != null)
{
Console.WriteLine("Inner Exception = ", ex.InnerException.Message);
}
}
}
}
Difference between throw,Throw Ex
When you use the throw
with an empty parameter, you are re-throwing the last exception. When you throw
the existing exception you are creating a new exception.
What's the difference? Simple: the stack trace.
The empty parameter re-throw and keeps the existing stack list, the parametered version creates a new stack trace to the point of the throw. For debugging, the empty version tells you where the error actually occurred, the parametered version discards that.
What's the difference? Simple: the stack trace.
The empty parameter re-throw and keeps the existing stack list, the parametered version creates a new stack trace to the point of the throw. For debugging, the empty version tells you where the error actually occurred, the parametered version discards that.
In Throw, the original exception stack trace
will be retained. To keep the original stack trace information, the correct
syntax is 'throw' without specifying an exception.
Declaration of throw
try
{
// do some operation that can fail
}
catch (Exception ex)
{
// do some local cleanup
throw;
}
|
Throw ex
In Throw ex, the original stack trace
information will get override and you will lose the original exception stack
trace. I.e. 'throw ex' resets the stack trace.
Declaration of throw ex
try
{
// do some operation that can fail
}
catch (Exception ex)
{
// do some local cleanup
throw ex;
}
}
|
·
throw ex resets the stack trace (so your errors would appear to
originate from HandleException)
·
throw doesn't - the original offender would be preserved.
You can see that in Exception 1, the stack trace goes back to
the DivByZero() method, whereas in Exception 2 it does not.
Take note, though, that the line number shown in ThrowException1() and ThrowException2() is the line number of the throw statement, not the line
number of the call to DivByZero(), which probably makes sense now that I think about it a
bit...
namespace KudVenkatCsharp
{
public class Aaa
{
static void Main(string[] args)
{
try
{
ThrowException1(); // line 19
}
catch (Exception x)
{
Console.WriteLine("Exception
1:");
Console.WriteLine(x.StackTrace);
Console.ReadLine();
}
try
{
ThrowException2(); // line 25
}
catch (Exception x)
{
Console.WriteLine("Exception
2:");
Console.WriteLine(x.StackTrace);
Console.ReadLine();
}
}
private static void ThrowException1()
{
try
{
DivByZero(); // line 34
}
catch
{
throw; // line 36
}
}
private static void ThrowException2()
{
try
{
DivByZero(); // line 41
}
catch (Exception ex)
{
throw ex; // line 43
}
}
private static void DivByZero()
{
int x = 0;
int y = 1 / x; // line 49
}
}
}
Checkout Notes