Exceptions Programming in C# Exceptions CSE 494R (proposed course for 459 Programming in C#) Prof....
-
Upload
irene-norton -
Category
Documents
-
view
227 -
download
1
Transcript of Exceptions Programming in C# Exceptions CSE 494R (proposed course for 459 Programming in C#) Prof....
Programming in C#ExceptionsExceptions
CSE 494R(proposed course for 459 Programming in C#)
Prof. Roger Crawfis
Slides are not finished
Not sure we will cover this topic.
Exceptional Situations
Sometimes, runtime errors are caused by unusual situations, not programming errors
For example: writing data to a fileMost of the time things go uneventfully, but...
The disk may be fullThere may be a hardware errorThe file may have been changed to read-only
Fragile code ignores the possibility of problems
Robust code anticipates such problems
The Traditional Method I
Traditional way of handling is to use "completion codes"
GET A FILENAMEOPEN THE FILEIF THERE IS NO ERROR OPENING THE FILE
READ SOME DATAIF THERE IS NO ERROR READING THE DATA
PROCESS THE DATAWRITE THE DATAIF THERE IS NO ERROR WRITING THE DATA
CLOSE THE FILEIF THERE IS NO ERROR CLOSING FILE
RETURN
The Traditional Method II
Things to notice with completion codesAlmost every step may fail, except "PROCESS
DATA"Program just be prepared to deal with failure
Very difficult to determine "normal" actionsSo concerned with things that can go wrong that it is hard
to tell if you are doing the right things in the right order
Difficult to use if library function contains such codeFunction must return several error codes so that user can
tell what went wrong
The Exceptional Method
Using exceptions the code looks like this
TRY TO DO THESE THINGS: GET A FILENAME OPEN THE FILE READ SOME DATA PROCESS THE DATA WRITE THE DATA CLOSE THE FILERETURNIF ERROR OPENING THE FILE THEN ...IF ERROR READING THE DATA THEN ...IF ERROR WRITING THE DATA THEN ...IF ERROR CLOSING THE FILE THEN ...
Exception Advantages
Compare methods of handling "bad things"Code that uses the exception strategy:
Is shorter and easier to readMakes the normal logic the main focus of the
method. In the completion code version, the error-handling code obscures the normal actions
Allows you to decide whether to handle the problem or defer handling the error on a case-by-case basis
Ideal for library-based code
Exception Objects
In C#, when a runtime error occursThe CLR sees the problem and creates an
ExceptionExceptionObject is from a subclass of System.ExceptionSystem.ExceptionClass ApplicationExceptionApplicationException : extend & recoverClass SystemExceptionSystemException : fix by proper coding
The exception object is thrown back up the call stack until a method is found that wants to catch it
If it is not "caught" then the CLR runtime system prints an error message
Following Exceptions
CLR Runtime
The Main( )method
First Method
ExceptionThrown Here
MethodCallsTravelDown
ExceptionsPassed
Up
Using try-catch
In C#, you handle exceptions with try-catchtry-catchPut the code that may cause an exceptional
situation into a “trytry” block.
Provide one or more “catchcatch” blocks immediately following the “trytry” block
You should provide catchcatch blocks for all errors you want to handle. Do this by choosing to catch particular classes.
If you don’t provide a catchcatch block for a particular exception, then the exception will be propagated up
The try-catch Syntax
08OOP12.WMF Figure 8-12 The try-catch
try { riskyBusiness(); } catch (SomeException e) { // Handle bad stuff }
Braces
Keyword
Braces
Statements or methods that maythrow exceptions
Keyword
Exceptionargument to becaught
Statements to deal with exceptional situation
The try block
The trytry block consists of:The keyword trytryFollowed by a brace-delimited blockBraces are required: part of the syntax
This is unlike loops and ifif statements
Inside the trytry blockPlace any number of statements that may
throw an exception
The catch Block
Place one or more immediately following trytry Nothing but whitespace or comments between
Syntax for catchcatch block is a little tricky
catch (Exception-Class [var1])catch (Exception-Class [var1]){{ // Handle exception 1 here// Handle exception 1 here}}catch (Exception-Class [var2])catch (Exception-Class [var2]){{ // Handle exception 2 here// Handle exception 2 here}}
A try-catch Example
Example : DivideByZeroTest.csFind on Q: drive in folder ch11\Fig11_01Drag and drop on F: or U: drive
Method Convert.ToInt32()Convert.ToInt32() will automatically detect for invalid representation of an integerMethod generates a FormatExceptionFormatException
CLR automatic detection for division by zeroOccurrence will cause a
DivideByZeroExceptionDivideByZeroException
Now, Finally, finally
When an exception is thrownControl jumps to the catchcatch block that handles itCode that releases resources may be skipped
Open FileOpen FileRead Data Read Data // Exception thrown here// Exception thrown hereClose File Close File // This is skipped. File still // This is skipped. File still openopen
The try-catchtry-catch has an optional finallyfinally partThis will always be calledUse to handle resource depletion
08OOP16.WMF Figure 8-16 The try-catch-finally
try { SomeResource thing; doSomethingWith(thing); } catch (SomeException e) { // Cope with tragic failure } finally { // This ALWAYS happens releaseResource(thing); }
Braces
Keyword
Braces
Statements or methods that maythrow exceptions
Keyword
Exceptionargument to be
caught
Statements to deal withexceptional situation
Braces
Keyword
Statements thatalways get executed
Throwing Exceptions
You aren't restricted to try-catch-finallytry-catch-finallyYou can throw exceptions as wellMust be an ExceptionException object or a subclass
if (numerator == 0)if (numerator == 0)throw new Exception("Illegal throw new Exception("Illegal
numerator");numerator");
You can rethrow a caught exception as wellExample: Figure 11-2, UsingExceptions.cs
Exception Object Properties
Properties for a caught exception [ Properties.cs ] MessageMessage : error message associated with an
exceptionMay be a default message or customized
StackTraceStackTrace : string representing the method call
stackList of "pending" methods when the exception occurredThe exact location is called the throw point
InnerExceptionInnerException property “Wrap” exception objects caught in codeThen throw new exception types
Defining Your Own Exceptions
Your program may have "application-specific" exceptions
To define your own exception classesDerive a new class from ApplicationExceptionApplicationException
For consistencies sake, name should end with “Exception”Should define three constructors
A default constructorA constructor that receives a string argumentA constructor that takes a string and an Exception argument
Example: NegativeNumberException.cs
Handling Integer Overflow
Traditionally, integer overflow is not a runtime error If a result is too large the answer is silently truncated
int ans = 400000 * 400000 / 400000;int ans = 400000 * 400000 / 400000;
C# allows you to change this on a calc-by-calc basis
int ans = checked( 400000 * 400000 / 400000);int ans = checked( 400000 * 400000 / 400000);
Throws an OverflowExceptionOverflowExceptionThere is a matching unchecked()unchecked() operatorExample: Overflow.cs
Exceptions in C#
Must inherit from System.Exception
Standard error handling in C#
Are thrown when: the code reaches a throw statement System exceptions occur (such as divide by zero)
No checked exceptions or exception specifications
Creating an Exception Class
Inherit ultimately from System.Exception
public class Exception1 : System.Exception{ public Exception1(string message) : base(message){}}
public class SomeException : Exception1{ public SomeException(string message) : base(message){}}
throw statement
Must throw an instance of an exception:throw(new MyException(“Error”));
May be used by itself only in a catch block: catch
{
throw;
}
Catching an Exception
A catch block is associated with a try block
A try block may have more than one catch block
catch blocks catch the exception type or any derived exception types passing through catch blocks are searched in the order they appear in the code catch blocks for specific types must come before the more general
types
An Empty catch clause will catch any type
catch clauses don’t need a variable name catch(Exception) is ok
catch blocks
void function1(){ try { // code } catch(Exception1 ex) { } catch(Exception ex) { }
// if no rethrow occurs // execution resumes here}
void function1(){ try { // code } catch(Exception ex) { } catch(Exception1 ex) { }}
Wrong Right
Exception Flow Control
void function1(){ try { try { throw(new SomeOtherException(“Error Message”)); } catch(Exception1 ex) { } } catch(Exception2 ex) { }}
The exception is passed up the call-stack until a suitable handler is found
Exception Flow Control
void function2(){ try { Function1(); } catch(Exception3 ex3) { } catch(Exception2 ex4) { } catch(Exception ex) { }}
If no suitable handler (catch clause) was found, the exception is passed to the calling method
Unhandled Exceptions
If no error handler is found the application terminates Control is passed back to Windows
finally block
Must be associated with a try block
a try block may have only one finally block
finally block always gets executed The appropriate catch clause is executed first
finally Flow Controlvoid function1(){ try { try { throw(new SomeException(“Error Message”)); } catch(Exception1 ex) { } finally { } } catch(Exception2 ex) { } finally { }}
Some Special Rules
Unhandled Exception in a destructor destructor stops executing, exception is discarded, base destructor is
called
catch (with no parameter) will catch unmanaged exceptions from other languages
Library Exceptions
Feel free to use these: ArithmeticException ArrayTypeMismatchException DivideByZeroException IndexOutOfRangeException InvalidCastException NullReferenceException OutOfMemoryException OverflowException StackOverflowException TypeInitializationException
System.Exception Class
Message string message associated with the exception
InnerException If this exception was generated inside an exception handler,
this refers to the original exception
Source Refers to the source class
StackTrace String representing the call stack, file and line number
Breaking On Exceptions
Debug | Exceptions (or Ctrl + D, E)
Exception Handling
Provides tremendous benefits
Requires a different way of thinking
The old way
RETVAL Process(int a, int x, int y, int z){RETVAL retval;if ((retval = function(x, y, z)) != OK)
return retval;
if ((retval = function2(a, y)) != OK)return retval;
}
Option 1
void Process(int a, int x, int y, int z){ try {
function(x, y, z);}catch (Exception e){
throw e;}
try {
function2(a, y);}catch (Exception e){
throw e;}
}
Option 2
void Process(int a, int x, int y, int z){ try {
function(x, y, z);function2(a, y);
}catch (Exception e){
throw e;}
}
Option 3
void Process(int a, int x, int y, int z){
function(x, y, z);function2(a, y);
}
Exception Handling
You get correct behavior by defaultOnly catch an exception when you can do
something useful for the userYou can write lots of unnecessary code, but
at least your code will be less robust
When to catch
Something specific happens, and we can help
trytry{{ StreamReader s = File.OpenText(filename);StreamReader s = File.OpenText(filename);}}
catch (Exception e)catch (Exception e){{ Console.WriteLine(“Invalid filename: {0}”, filename);Console.WriteLine(“Invalid filename: {0}”, filename);}}
trytry{{ StreamReader s = File.OpenText(filename);StreamReader s = File.OpenText(filename);}}
catch (FileNotFoundException e)catch (FileNotFoundException e){{ Console.WriteLine(e);Console.WriteLine(e);}}
trytry{{ ExecuteBigProcess();ExecuteBigProcess();}}
catch (Exception e)catch (Exception e){{ log.WriteLine(e.ToString());log.WriteLine(e.ToString()); throw;throw;}}
trytry{{ ExecuteBigProcess();ExecuteBigProcess();}}
catch (Exception e)catch (Exception e){{ throw new throw new MyException(“Error executing BigProcess”, e); MyException(“Error executing BigProcess”, e);}}
When to catch
We need to log or wrap an exception
When to catch
Process would die otherwisepublic static void Main()public static void Main(){{ while (true)while (true) {{ trytry {{ MainLoop();MainLoop(); }} catch (Exception e)catch (Exception e) {{ Console.WriteLine(“Exception caught, trying to continue”);Console.WriteLine(“Exception caught, trying to continue”); Console.WriteLine(e);Console.WriteLine(e); }} }}}}
Finally statement
If an exception is thrown andThere’s something to clean up
Close a fileRelease a DB handle
Using statement makes this easierWorks on anything that implements IDisposable
Using Statement
Acquire, Execute, Release patternWorks with any IDisposable object
Data access classes, streams, text readers and writers, network classes, etc.
using (Resource res = new Resource()) {using (Resource res = new Resource()) { res.DoWork();res.DoWork();}}
Resource res = new Resource(...);Resource res = new Resource(...);try {try { res.DoWork();res.DoWork();}}finally {finally { if (res != null) ((IDisposable)res).Dispose();if (res != null) ((IDisposable)res).Dispose();}}
Using Statement
static void Copy(string sourceName, string destName) {static void Copy(string sourceName, string destName) { Stream input = File.OpenRead(sourceName);Stream input = File.OpenRead(sourceName); Stream output = File.Create(destName);Stream output = File.Create(destName); byte[] b = new byte[65536];byte[] b = new byte[65536]; int n;int n; while ((n = input.Read(b, 0, b.Length)) != 0) {while ((n = input.Read(b, 0, b.Length)) != 0) { output.Write(b, 0, n);output.Write(b, 0, n); }} output.Close();output.Close(); input.Close();input.Close();}}
static void Copy(string sourceName, string destName) {static void Copy(string sourceName, string destName) { Stream input = File.OpenRead(sourceName);Stream input = File.OpenRead(sourceName); try {try { Stream output = File.Create(destName);Stream output = File.Create(destName); try {try { byte[] b = new byte[65536];byte[] b = new byte[65536]; int n;int n; while ((n = input.Read(b, 0, b.Length)) != 0) {while ((n = input.Read(b, 0, b.Length)) != 0) { output.Write(b, 0, n);output.Write(b, 0, n); }} }} finally {finally { output.Close();output.Close(); }} }} finally {finally { input.Close();input.Close(); }}}}
static void Copy(string sourceName, string destName) {static void Copy(string sourceName, string destName) { using (Stream input = File.OpenRead(sourceName))using (Stream input = File.OpenRead(sourceName)) using (Stream output = File.Create(destName)) {using (Stream output = File.Create(destName)) { byte[] b = new byte[65536];byte[] b = new byte[65536]; int n;int n; while ((n = input.Read(b, 0, b.Length)) != 0) {while ((n = input.Read(b, 0, b.Length)) != 0) { output.Write(b, 0, n);output.Write(b, 0, n); }} }}}}
Exceptions vs Return Codes
Exceptions are meant for exceptional cases Invalid parametersCan’t perform operation
Should not occur during normal program operationUser interaction is a grey area
Using Return Values
Okay if your caller always will have to check and recover from somethingMake sure you don’t force them to write:
Shouldn’t be possible to do the wrong thingFile.Open() returns null on file not foundYou can’t ignore this
bool success = TryOperation(param1, param2);bool success = TryOperation(param1, param2);if (!success)if (!success) return success;return success;
Summary
Understand how the model worksDon’t work too hardIf you can’t do something useful, don’t
catch
Programming in C# ExceptionsExceptions
CSE 494R(proposed course for 459 Programming in C#)
Prof. Roger Crawfis
Programming in C#XML DocumentationXML Documentation
CSE 494R(proposed course for 459 Programming in C#)
Prof. Roger Crawfis
Programming in C# XML DocumentationXML Documentation
CSE 494R(proposed course for 459 Programming in C#)
Prof. Roger Crawfis