CSharp Articles

Exception Handling in .NET

Introduction

Exception handling is made easier and streamlined in .Net. It uses the Exception objects to cascade the exception between layers and allows handling them at any layer. An object of an Exception is that describe the exceptional conditions occur in a code. That means, we are catching an exception, creating an object of it, and then handling it or throwing it to the next level.

Exceptions

Exceptions are responses to abnormal or exceptional conditions that arise at runtime. These error are generated when the applications is running. If they are not handled in proper fashion the application will fail to execute. Handling Exception means foresee the situations were runtime exceptions could arise, and implement measures to rectify the probable error or to facilitate smooth exit of the application. A typical example for an exception is division by zero. Consider the code :

int Result = x/y;

During coding we are not sure whether the variable ‘y’ may take value ‘0’ at some point of execution. As it is a variable there is every chance that it may take value ‘0’. When this happens the operation is not defined so system will fail to execute the instruction, causing a runtime error and application failure. This is an exception, which needs to be handled. A usual exception-handling situation for the above case can be as follows:

int Result;

if(y != 0)

Result = (x/y);

else

Console.WriteLine(“Division Can not be performed, Y = 0”);

Practically it may not be possible to identify and handle the exceptions as we discussed. The causes of exception can be many and we may not be able to go for such simple conditional checks to handle exception. Here comes the need for systematic and structured Exception handling methods. The advantages of proper exception handling are:

• Avoid abrupt and unsuccessful termination of application.

• They do not need to be to be handled at the point where error took place. This makes them very suitable for library or system code, which can signal an error and leave us to handle it

• They can be used when passing back a return value cannot be used.

Exception handling in .Net

The common language runtime provides an exception handling model that is based on the representation of exceptions as objects, and the separation of program code and exception handling code into try block and catch block, respectively. The code part which you suspect to cause exception is put in a try block. When some exception is thrown in this portion the control is shifted to the instructions in one of the catch block handling the particular exception thrown. There can be one or more catch blocks, each designed to handle a particular type of exception, or one block designed to catch a more specific exception than another block. The Exception class hierarchy will be discussed later, then you will have better understanding of the Exception Classes.

Taking the same example we will see how this try …catch…finally blocks are implemented for exception handling.

int Result;

try

{

Result = (x/y);

}

catch(Exception)

{

Console.WriteLine(“Division Can not be performed, Y = 0”);

}

finally

{

Console.WriteLine(“Inside Finally”);

}

Here, when the value of ‘y’ is ‘0’ the ‘DivideByZeroException’, a System Exception is thrown. In the ‘catch’ block we are catching all the exception as we are specifying the outer exception class. So the when the division instruction is processed control shifts to the catch block, printing the given statement. Then control goes to ‘finally’ block, as ‘finally’ block will be executed in all cases. If there is chance for more than one exception in a part of code and we need to handle each exception in different ways we can have different catch blocks for one ‘try’ block and can handle them as required. In this case the control shifts from ‘try’ block to the corresponding ‘catch’ block based on the Exception thrown.

The use of ‘finally’ block can be well appreciated when we have to perform some operation irrespective of the exception thrown or successful completion of the operation. Best example can be releasing of some resources, like closing database connection.

System exceptions are severe exceptions and are non recoverable. It is not recommended to catch System Exceptions or to throw System Exceptions from application.

Application exceptions are thrown from user program rather than from runtime. The user defined custom exceptions are derived from this exception class. Application Exception Class in derived from Exception class but does not add new functionality.

Following are some common Exception Classes with their functionality briefed:

• AccessException – Failure to access a type member, such as a method or field.

• ArgumentException – An argument to a method was invalid.

• ArgumentNullException – A null argument was passed to a method that doesn’t accept it.

• ArgumentOutOfRangeException – Argument value is out of range.

• ArithmeticException – Arithmetic over – or underflow has occurred.

• ArrayTypeMismatchException – Attempt to store the wrong type of object in an array.

• BadImageFormatException – Image is in the wrong format.

• CoreException – Base class for exceptions thrown by the runtime.

• DivideByZeroException – An attempt was made to divide by zero.

• FormatException – The format of an argument is wrong.

• IndexOutOfRangeException – An array index is out of bounds.

• InvalidCastExpression – An attempt was made to cast to an invalid class.

• InvalidOperationException – A method was called at an invalid time.

• MissingMemberException – An invalid version of a DLL was accessed.

• NotFiniteNumberException – A number is not valid.

• NotSupportedException – Indicates that a class does not implement a method.

• NullReferenceException – Attempt to use an unassigned reference.

• OutOfMemoryException – Not enough memory to continue execution.

• StackOverflowException – A stack has over flown.

The Exception Object

Now we will familiarize Exception object. The exception Class Properties include

1. StackTrace: This is for debugging information. This gives the file name and the line number where the exception occurred.

2. InnerException: This property helps to give the full exception path incase of cascaded and encapsulated exceptions. That is the root exception details can be captured as InnerException in the next layer where it caught and escalated. This gives more information to the next layer.

3. Message: Gives information about the cause of exception. Customised messages can be used for custom exceptions.

4. HelpLink: Holds URL, which gives more information on cause of the exception.

Exception Class is having four constructors:

1. Default Constructor: Exception(), which does not take any arguments and create one Exception object with default properties.

2. Exception(string): Takes a string and sets it as Message Property.

3. Exception(string, Exception): Takes and Sets Message and Inner Exception Properties.

4. Exception(SerializationInfo, StreamingContext): This Takes Serialisation Info and Streaming context. This constructor is used when the Exception object has to be de-serialized to reconstitute the object from a stream. The SerializationInfo object holds the serialized object data and the StreamingContext object holds the information about source/destination stream.

These properties and constructors helps to instantiate and manipulate Exception objects.

Custom Exceptions

.Net allows user to define custom exceptions and use them. It helps for encapsulation of exceptions occurred in higher layers and pass more customized information to the subsequent layers. The user defined custom exceptions should inherit from the Exception Class or any of its subclasses.

The following example shows how to define a custom exception:

using System;

public class EmployeeListNotFoundException : ApplicationException

{

public EmployeeListNotFoundException()

{

}

public EmployeeListNotFoundException(string message): base(message)

{

}

public EmployeeListNotFoundException(string message, Exception inner)

: base(message, inner)

{

}

}

Here we are defining a custom exception EmployeeListNotFoundException, which is inherited from ApplicationException. Application exceptions are exceptions thrown by user program rather than the runtime. User defined exceptions are derived from this exception class which is derived from Exception Class.

It overrides the base class constructors, and any customized info can be passed implementing this class.

Throw Keyword

An Exception object can be thrown to the next level using ‘throw’ keyword. This is done when we are not handling the exception where it is occurred but is escalated to next level. Here we can just throw the exception generated or can catch it and throw a custom Exception object. To understand better, consider the above example.

int Result;

try

{

Result = (x/y);

}

catch(Exception)

{

throw new EmployeeListNotFoundException();

}

finally

{

Console.WriteLine(“Inside Finally”);

}

Here we are catching the exception and throwing our custom exception to the next level. Make sure that the exception class is defined and metadata is available to the code where we are referring the Exception.

If exception is not handled where it is generated, the exception will be bubbled up the call stack until it either finds an appropriate error handler, or the common language runtime default error handler handles it. If you want to pass standard runtime exceptions to the subsequent layers, no additional coding is necessary. It will happen automatically.

Few Points to Note

Exceptions should be caught and handled where they occur as far as possible. When it is more appropriate to cascade to the next level, throw custom Exception defined for the specific situation, to facilitate understanding to the next level. Don’t throw general Exceptions, which hide the real cause of exception.

All custom exception definition and usage should be properly documented.

If the component uses any external component, all the exceptions thrown by the external component should be caught and handled. Handling can be throwing a custom exception. But never escalate the external component exception to the next level or component.

Conclusion

Structured Exception handling helps to manage the abnormal errors arises at runtime. They ensure smooth exiting of the application and release of various resources even in case non-recoverable errors. The Exceptions can be handled where they are generated or cascaded to next level for better handling with all the information.

Categories: CSharp Articles

Leave a Reply