Sunteți pe pagina 1din 12

Unit 3: Exception

Handling
Unit 3
Ode to Errors, Bugs, and Exceptions
The Role of .NET Exception Handing,
The Simplest possible example
Throwing generic exceptions
Catching exceptions,
Configuring the state of an exception-Target Site
Stack trace, Helplink & data property
System Level Exception
Application-Level Exception
Prof. Sushant S.Sundikar Processing Multiple Exception
Generic catch statements,
Sahaj Computer Solutions
Rethrowing exception
9945323277 Inner exceptions
The Finally Block
0831-4200864 Who is throwing what?
The result of unhandled exceptions
www.sahajsolns.com Debugging Unhandled exceptions using VS. NET IDE.
Unit 3: Exception Handling 1

Ode to Errors, Bugs, and Exceptions


Writing software is a complex undertaking, and given this complexity, it is quite common for even
the best software to ship with various problems. Now, regardless of the cause of said problem, the
end result is that your application does not work as expected lets see three commonly used
anomaly-centric terms:

Bugs: This is, simply put, an error on the part of the programmer. For example, assume you are
programming with unmanaged C++. If you make calls on a NULL pointer or fail to delete allocated
memory (resulting in a memory leak), you have a bug.

User errors: Unlike bugs, user errors are typically caused by the individual running your application,
rather than by those who created it. For example, an end user who enters a malformed string into a
text box could very well generate an error if you fail to handle this faulty input in your code base.

Exceptions: Exceptions are typically regarded as runtime anomalies that are difficult, if not
impossible, to track for while programming your application. Possible exceptions include attempting
to connect to a database that no longer exists, opening a corrupted file, or contacting a machine that
is currently offline. In each of these cases, the programmer (and end user) has little control over
these exceptional circumstances.

The Role of .NET Exception Handing,


The .NET platform provides a standard technique to send and trap runtime errors: structured
exception handling (SEH). C# exception handling is managed via four keywords: try, catch, throw, and
finally. They form an interrelated subsystem in which the use of one implies the use of another.

Program statements that you want to monitor for exceptions are contained within a try block. If an
exception occurs within the try block, it is thrown. Your code can catch this exception using catch
and handle it in some rational manner. System-generated exceptions are automatically thrown by
the runtime system. To manually throw an exception, use the keyword throw. Any code that
absolutely must be executed upon exiting from a try block is put in a finally block.

Using try and catch


Here is the general form of the try/catch exception-handling blocks:

try {

// block of code to monitor for errors

catch (ExcepType1 exOb) {

// handler for ExcepType1

catch (ExcepType2 exOb) {

Prof Sushant S. Sundikar C# Programming


Unit 3: Exception Handling 2

// handler for ExcepType2

The Simplest possible example


Here is a simple example that illustrates how to watch for and catch an exception. As you know, it is
an error to attempt to index an array beyond its boundaries. When this error occurs, the CLR throws
an IndexOutOfRangeException, which is a standard exception defined by the .NET Framework. The
following program purposely generates such an exception and then catches it:

// Program: ch03pg01.cs

// Program to demonstrate exception handling.

using System;

class ExcDemo1 {

static void Main() {

int[] nums = new int[4];

try {

Console.WriteLine("Before exception is generated.");

// Generate an index out-of-bounds exception.

for(int i=0; i < 10; i++) {

nums[i] = i;

Console.WriteLine("nums[{0}]: {1}", i, nums[i]);

Console.WriteLine("this won't be displayed");

catch (IndexOutOfRangeException) {

// Catch the exception.

Console.WriteLine("Index out-of-bounds!");

Console.WriteLine("After catch block.");

Prof Sushant S. Sundikar C# Programming


Unit 3: Exception Handling 3

Processing Multiple Exception


You can associate more than one catch clause with a try. In fact, it is common to do so. However,
each catch must catch a different type of exception. For example, the program shown here catches
both array boundary and divide-by-zero errors:

// Use multiple catch clauses.

using System;

class MultiCatchDemo {

static void Main() {

// Here, numer is longer than denom.

int[] numer = { 4, 8, 16, 32, 64, 128, 256, 512 };

int[] denom = { 2, 0, 4, 4, 0, 8 };

for(int i=0; i < numer.Length; i++) {

try {

Console.WriteLine(numer[i] + " / " +

denom[i] + " is " +

numer[i]/denom[i]);

catch (DivideByZeroException) {

Console.WriteLine("Can't divide by Zero!");

catch (IndexOutOfRangeException) {

Console.WriteLine("No matching element found.");

Generic catch statements


Occasionally, you might want to catch all exceptions, no matter the type. To do this, use a catch
clause that specifies no exception type or variable. It has this general form:

catch {

// handle exceptions

Prof Sushant S. Sundikar C# Programming


Unit 3: Exception Handling 4

For example:

try {

Console.WriteLine(numer[i] + " / " + denom[i] + " is " +


numer[i]/denom[i]);

catch { // A "catch-all" catch.

Console.WriteLine("Some exception occurred.");

Throwing generic exceptions


It is possible to throw an exception manually by using the throw statement. Its general form is
shown here:

throw exceptOb;

The exceptOb must be an object of an exception class derived from Exception.

Program ch03pg02.cs: Here is an example that illustrates the throw statement by manually
throwing a DivideByZeroException.

Rethrowing exception
An exception caught by one catch can be rethrown so that it can be caught by an outer catch. The
most likely reason for rethrowing an exception is to allow multiple handlers access to the exception.
To rethrow an exception, you simply specify throw, without specifying an expression. That is, you
use this form of throw:

throw;

Program ch03pg03.cs : The following program illustrates rethrowing an exception. In this case, it
rethrows an IndexOutOfRangeException.

Configuring the state of an exception


The TargetSite Property
The System.Exception.TargetSite property allows you to determine various details about the method
that threw a given exception. However, TargetSite does not simply return a vanilla-flavored string,
but a strongly typed System.Reflection. MethodBase object. This type can be used to gather
numerous details regarding the offending method as well as the class that defines the offending
method.

Prof Sushant S. Sundikar C# Programming


Unit 3: Exception Handling 5

The StackTrace Property


The System.Exception.StackTrace property allows you to identify the series of calls that resulted in
the exception. Be aware that you never set the value of StackTrace as it is established automatically
at the time the exception is created.

The HelpLink Property


While the TargetSite and StackTrace properties allow programmers to gain an understanding of a
given exception, this information is of little use to the end user. The System.Exception.Message
property can be used to obtain human-readable information that may be displayed to the current
user. In addition, the HelpLink property can be set to point the user to a specific URL or standard
Windows help file that contains more detailed information.

By default, the value managed by the HelpLink property is an empty string. If you wish to fill this
property with an interesting value, you will need to do so before throwing the System.Exception
type.

For example:

// We need to call the HelpLink property, thus we need to create a local variable before throwing
the Exception object.

Exception ex = new Exception(string.Format("{0} has overheated!",


petName));

ex.HelpLink = "http://www.CarsRUs.com";

throw ex;

The catch logic could now be updated to print out this help link information as follows:

catch(Exception e)

Console.WriteLine("Help Link: {0}", e.HelpLink);

System Level Exception


Exceptions that are thrown by the CLR are (appropriately) called system exceptions. These exceptions
are regarded as nonrecoverable, fatal errors. System exceptions derive directly from a base class
named System.SystemException, which in turn derives from System.Exception (which derives
from System.Object):

public class SystemException : Exception

// Various constructors.

Prof Sushant S. Sundikar C# Programming


Unit 3: Exception Handling 6

Common Exception Classes


Exception class name Description

System.ArithmeticException A base class for exceptions that occur during


arithmetic operations, such as
System.DivideByZeroException and
System.OverflowException.

System.DivideByZeroException Thrown when an attempt to divide an integral value


by zero occurs.

System.IndexOutOfRangeException Thrown when an attempt to index an array via an


index that is less than zero or outside the bounds of
the array.

System.InvalidCastException Thrown when an explicit conversion from a base type


or interface to a derived type fails at run time.

System.NullReferenceException Thrown when a null reference is used in a way that


causes the referenced object to be required.

System.OutOfMemoryException Thrown when an attempt to allocate memory (via


new) fails.

Application-Level Exception
Given that all .NET exceptions are class types, you are free to create your own application-specific
exceptions. However, due to the fact that the System.SystemException base class represents
exceptions thrown from the CLR, you may naturally assume that you should derive your custom
exceptions from the System.Exception type. While you could do so, best practice dictates that you
instead derive from the System.ApplicationException type:

public class ApplicationException : Exception

// Various constructors.

Prof Sushant S. Sundikar C# Programming


Unit 3: Exception Handling 7

Inner exceptions
One try block can be nested within another. An exception generated within the inner try block that
is not caught by a catch associated with that try is propagated to the outer try block. For example,
here the IndexOutOfRangeException is not caught by the inner try block, but by the outer try:

// Use a nested try block.

using System;

class NestTrys {

static void Main() {

// Here, numer is longer than denom.

int[] numer = { 4, 8, 16, 32, 64, 128, 256, 512 };

int[] denom = { 2, 0, 4, 4, 0, 8 };

try { // outer try

for(int i=0; i < numer.Length; i++) {

try { // nested try

Console.WriteLine(numer[i] + " / " +

denom[i] + " is " +

numer[i]/denom[i]);

catch (DivideByZeroException) {

Console.WriteLine("Can't divide by Zero!");

catch (IndexOutOfRangeException) {

Console.WriteLine("No matching element found.");

Console.WriteLine("Fatal error -- program terminated.");

Prof Sushant S. Sundikar C# Programming


Unit 3: Exception Handling 8

The output from the program is shown here:

4 / 2 is 2

Can't divide by Zero!

16 / 4 is 4

The Finally Block


Sometimes you will want to define a block of code that will execute when a try/catch block is left.
For example, an exception might cause an error that terminates the current method, causing its
premature return. However, that method may have opened a file or a network connection that
needs to be closed. Such types of circumstances are common in programming, and C# provides a
convenient way to handle them: finally.

To specify a block of code to execute when a try/catch block is exited, include a finally block at the
end of a try/catch sequence. The general form of a try/catch that includes finally is shown here:

try {

// block of code to monitor for errors

catch (ExcepType1 exOb) {

// handler for ExcepType1

finally {

// finally code

The finally block will be executed whenever execution leaves a try/catch block, no matter what
conditions cause it. That is, whether the try block ends normally, or because of an exception, the
last code executed is that defined by finally. The finally block is also executed if any code within
the try block or any of its catch blocks returns from the method .Here is an example of finally:

// Use finally.
using System;
class UseFinally
{
public static void GenException(int what)
{
int t;
int[] nums = new int[2];
Console.WriteLine("Receiving " + what);

Prof Sushant S. Sundikar C# Programming


Unit 3: Exception Handling 9

try
{
switch(what)
{
case 0:
t = 10 / what; // generate div-by-zero error
break;
case 1:
nums[4] = 4; // generate array index error
break;
case 2:
return; // return from try block
}
}
catch (DivideByZeroException)
{
Console.WriteLine("Can't divide by Zero!");
return; // return from catch
}
catch (IndexOutOfRangeException)
{
Console.WriteLine("No matching element found.");
}
finally {
Console.WriteLine("Leaving try.");
}
}
}

class FinallyDemo
{
static void Main()
{
for(int i=0; i < 3; i++)
{
UseFinally.GenException(i);
Console.WriteLine();
}
}
}

Here is the output produced by the program:

Receiving 0
Can't divide by Zero!
Leaving try.
Receiving 1

Prof Sushant S. Sundikar C# Programming


Unit 3: Exception Handling 10

No matching element found.


Leaving try.
Receiving 2
Leaving try.

The result of unhandled exceptions


Catching one of the standard exceptions, as the preceding program does, has a side benefit: It
prevents abnormal program termination. When an exception is thrown, it must be caught by some
piece of code, somewhere. In general, if your program does not catch an exception, it will be caught
by the runtime system. The trouble is that the runtime system will report an error and terminate the
program.

// Let the C# runtime system handle the error.

using System;

class NotHandled {

static void Main() {

int[] nums = new int[4];

Console.WriteLine("Before exception is generated.");

// Generate an index out-of-bounds exception.

for(int i=0; i < 10; i++) {

nums[i] = i;

Console.WriteLine("nums[{0}]: {1}", i, nums[i]);

When the array index error occurs, execution is halted and the following error message is displayed:

Unhandled Exception: System.IndexOutOfRangeException:

Index was outside the bounds of the array.

at NotHandled.Main()

Although such a message is useful while debugging, you would not want others to see it, to say the
least! This is why it is important for your program to handle exceptions itself.

Prof Sushant S. Sundikar C# Programming


Unit 3: Exception Handling 11

Debugging Unhandled exceptions using VS. NET IDE.

To wrap things up, do be aware that Visual Studio 2005 provides a number of tools that help you
debug unhandled custom exceptions. If you were to start a debugging session (using the Debug Start
menu selection), Visual Studio automatically breaks at the time the uncaught exception is thrown.
Better yet, you are presented with a window (see Figure 3-1) displaying the value of the Message
property.

Prof Sushant S. Sundikar C# Programming

S-ar putea să vă placă și