unit 3: exception handling · exception handling (seh). c# exception handling is managed via four...

12
Unit 3: Exception Handling Prof. Sushant S.Sundikar Sahaj Computer Solutions 9945323277 0831-4200864 www.sahajsolns.com 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 Processing Multiple Exception Generic catch statements, Rethrowing exception Inner exceptions The Finally Block Who is throwing what? The result of unhandled exceptions Debugging Unhandled exceptions using VS. NET IDE.

Upload: others

Post on 01-Oct-2020

36 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Unit 3: Exception Handling · exception handling (SEH). C# exception handling is managed via four keywords: try, catch, throw, and finally. They form an interrelated subsystem in

Unit 3: Exception

Handling

P r o f . S u s h a n t S . S u n d i k a r

S a h a j C o m p u t e r S o l u t i o n s

9 9 4 5 3 2 3 2 7 7

0 8 3 1 - 4 2 0 0 8 6 4

w w w . s a h a j s o l n s . c o m

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

• Processing Multiple Exception

• Generic catch statements,

• Rethrowing exception

• Inner exceptions

• The Finally Block

• Who is throwing what?

• The result of unhandled exceptions

• Debugging Unhandled exceptions using VS. NET IDE.

Page 2: Unit 3: Exception Handling · exception handling (SEH). C# exception handling is managed via four keywords: try, catch, throw, and finally. They form an interrelated subsystem in

Unit 3: Exception Handling 1

Prof Sushant S. Sundikar C# Programming

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 let’s 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) {

Page 3: Unit 3: Exception Handling · exception handling (SEH). C# exception handling is managed via four keywords: try, catch, throw, and finally. They form an interrelated subsystem in

Unit 3: Exception Handling 2

Prof Sushant S. Sundikar C# Programming

// 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.");

}

}

Page 4: Unit 3: Exception Handling · exception handling (SEH). C# exception handling is managed via four keywords: try, catch, throw, and finally. They form an interrelated subsystem in

Unit 3: Exception Handling 3

Prof Sushant S. Sundikar C# Programming

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

Page 5: Unit 3: Exception Handling · exception handling (SEH). C# exception handling is managed via four keywords: try, catch, throw, and finally. They form an interrelated subsystem in

Unit 3: Exception Handling 4

Prof Sushant S. Sundikar C# Programming

}

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.

Page 6: Unit 3: Exception Handling · exception handling (SEH). C# exception handling is managed via four keywords: try, catch, throw, and finally. They form an interrelated subsystem in

Unit 3: Exception Handling 5

Prof Sushant S. Sundikar C# Programming

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.

Page 7: Unit 3: Exception Handling · exception handling (SEH). C# exception handling is managed via four keywords: try, catch, throw, and finally. They form an interrelated subsystem in

Unit 3: Exception Handling 6

Prof Sushant S. Sundikar C# Programming

}

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.

}

Page 8: Unit 3: Exception Handling · exception handling (SEH). C# exception handling is managed via four keywords: try, catch, throw, and finally. They form an interrelated subsystem in

Unit 3: Exception Handling 7

Prof Sushant S. Sundikar C# Programming

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.");

}

}

}

Page 9: Unit 3: Exception Handling · exception handling (SEH). C# exception handling is managed via four keywords: try, catch, throw, and finally. They form an interrelated subsystem in

Unit 3: Exception Handling 8

Prof Sushant S. Sundikar C# Programming

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);

Page 10: Unit 3: Exception Handling · exception handling (SEH). C# exception handling is managed via four keywords: try, catch, throw, and finally. They form an interrelated subsystem in

Unit 3: Exception Handling 9

Prof Sushant S. Sundikar C# Programming

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

Page 11: Unit 3: Exception Handling · exception handling (SEH). C# exception handling is managed via four keywords: try, catch, throw, and finally. They form an interrelated subsystem in

Unit 3: Exception Handling 10

Prof Sushant S. Sundikar C# Programming

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.

Page 12: Unit 3: Exception Handling · exception handling (SEH). C# exception handling is managed via four keywords: try, catch, throw, and finally. They form an interrelated subsystem in

Unit 3: Exception Handling 11

Prof Sushant S. Sundikar C# Programming

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.