Chapter 11 – Exception Handling Outline Exception Handling Overview Catching Exceptions Example: DivideByZeroException .NET Exception Hierarchy Exception Properties Throwing Exceptions Rethrowing Exceptions Programmer-Defined Exception Classes Handling Overflows
Exception Handling Overview Program detects error Throws exception (throw point) Caught by exception handler Handled Uncaught (no appropriate exception handler) Debug mode Ignore, continue execution View in debugger Standard execution mode Terminate
Catch blocks (Catch handlers) Catching Exceptions Try block Encloses code in which errors (exceptions) may occur Catch blocks (Catch handlers) Appear after Try block Parameter included Handles specific exception type Parameterless Handles all exception types Finally block Appears after last Catch handler Optional (if one or more catch handlers exist) Encloses code that always executes (whether exception occurs or not)
DivideByZeroTest.vb 1 ' Fig. 11.1: DivideByZeroTest.vb 2 ' Basics of Visual Basic exception handling. 3 4 Imports System.Windows.Forms.Form 5 6 Public Class FrmDivideByZero 7 Inherits Form 8 9 ' label and TextBox for specifying numerator 10 Friend WithEvents lblNumerator As Label 11 Friend WithEvents txtNumerator As TextBox 12 13 ' label and TextBox for specifying denominator 14 Friend WithEvents lblDenominator As Label 15 Friend WithEvents txtDenominator As TextBox 16 17 ' button for dividing numerator by denominator 18 Friend WithEvents cmdDivide As Button 19 20 Friend WithEvents lblOutput As Label ' output for division 21 22 ' Windows Form Designer generated code 23 24 ' obtain integers from user and divide numerator by denominator 25 Private Sub cmdDivide_Click(ByVal sender As System.Object, _ 26 ByVal e As System.EventArgs) Handles cmdDivide.Click 27 28 lblOutput.Text = "" 29 DivideByZeroTest.vb
DivideByZeroTest.vb 30 ' retrieve user input and call Quotient 31 Try 32 33 ' Convert.ToInt32 generates FormatException if argument 34 ' is not an integer 35 Dim numerator As Integer = _ 36 Convert.ToInt32(txtNumerator.Text) 37 38 Dim denominator As Integer = _ 39 Convert.ToInt32(txtDenominator.Text) 40 41 ' division generates DivideByZeroException if 42 ' denominator is 0 43 Dim result As Integer = numerator \ denominator 44 45 lblOutput.Text = result.ToString() 46 47 ' process invalid number format 48 Catch formattingException As FormatException 49 MessageBox.Show("You must enter two integers", _ 50 "Invalid Number Format", MessageBoxButtons.OK, _ 51 MessageBoxIcon.Error) 52 53 ' user attempted to divide by zero 54 Catch dividingException As DivideByZeroException 55 MessageBox.Show(dividingException.Message, _ 56 "Attempted to Divide by Zero", _ 57 MessageBoxButtons.OK, MessageBoxIcon.Error) 58 59 End Try 60 61 End Sub ' cmdDivide_Click 62 63 End Class ' FrmDivideByZero DivideByZeroTest.vb
DivideByZeroTest.vb
.NET Exception Hierarchy Class Exception Base class of .NET Framework exception hierarchy Important classes derived from Exception ApplicationException Can create exception data types specific to applications SystemException Runtime exceptions Can occur anytime during execution Avoid with proper coding
.NET Exception Hierarchy Benefit of hierarchy Inheritance If handling behavior same for base and derived classes Able to catch base class Otherwise catch derived classes individually Ex. Catch handler with parameter type Exception Able to catch all exceptions
Exception Properties Property Message Property InnerException (...) Stores exception object’s error message Default message Associated with exception type Customized message Passed to exception object’s constructor Property InnerException Allows programmers to “wrap” exception objects with other exception objects Original exception object becomes InnerException of new exception object Benefit Allows programmers to provide more information about particular exceptions (...)
Throwing Exceptions Public Class Racional (...) Public Sub New(ByVal num As Integer, ByVal denom As Integer) If denom = 0 Then Throw New DivideByZeroException("denominador nulo") End If (...) End Sub End Class .NET Framework Class Library DivideByZeroException Class The exception that is thrown when there is an attempt to divide an integral or decimal value by zero. System.Object System.Exception System.SystemException System.ArithmeticException System.DivideByZeroException
Rethrowing Exceptions Public Class Racional (...) Public Shared Function FromString(ByVal str As String) As Racional Dim i, num, denom As Integer Try i = str.IndexOf("/") num = str.Substring(0, i) denom = str.Substring(i + 1) Catch e As Exception Throw New ArgumentException("Argumento não válido", e.Message) End Try Return New Racional(num, denom) End Function End Class
Programmer-Defined Exception Classes Programmer-defined exceptions should: Derive directly/indirectly from class ApplicationException Have class name ending in “Exception” Define three constructors Default constructor Constructor that receives String argument The error message Constructor that receives String argument and an Exception argument The InnerException object
NegativeNumberException.vb 1 ' Fig. 11.4: NegativeNumberException.vb 2 ' NegativeNumberException represents exceptions caused by 3 ' illegal operations performed on negative numbers. 4 5 Public Class NegativeNumberException 6 Inherits ApplicationException 7 8 ' default constructor 9 Public Sub New() 10 MyBase.New("Illegal operation for a negative number") 11 End Sub 12 13 ' constructor for customizing error message 14 Public Sub New(ByVal messageValue As String) 15 MyBase.New(messageValue) 16 End Sub 17 18 ' constructor for customizing error message and specifying 19 ' inner exception object 20 Public Sub New(ByVal messageValue As String, _ 21 ByVal inner As Exception) 22 23 MyBase.New(messageValue, inner) 24 End Sub 25 26 End Class ' NegativeNumberException NegativeNumberException.vb
SquareRootTest.vb 1 ' Fig. 11.5: SquareRootTest.vb 2 ' Demonstrating a user-defined exception class. 3 4 Imports System.Windows.Forms 5 6 Public Class FrmSquareRoot 7 Inherits Form 8 9 ' Label for showing square root 10 Friend WithEvents lblOutput As Label 11 Friend WithEvents lblInput As Label 12 13 ' Button invokes square-root calculation 14 Friend WithEvents cmdSquareRoot As Button 15 16 ' TextBox receives user's Integer input 17 Friend WithEvents txtInput As TextBox 18 19 ' Windows Form Designer generated code 20 21 ' computes square root of parameter; throws 22 ' NegativeNumberException if parameter is negative 23 Public Function SquareRoot(ByVal operand As Double) As Double 24 25 ' if negative operand, throw NegativeNumberException 26 If operand < 0 Then 27 Throw New NegativeNumberException( _ 28 "Square root of negative number not permitted") 29 30 End If 31 32 ' compute square root 33 Return Math.Sqrt(operand) 34 35 End Function ' cmdSquareRoot SquareRootTest.vb
36 37 ' obtain user input, convert to double and calculate square root 38 Private Sub cmdSquareRoot_Click( _ 39 ByVal sender As System.Object, _ 40 ByVal e As System.EventArgs) Handles cmdSquareRoot.Click 41 42 lblOutput.Text = "" 43 44 ' catch any NegativeNumberException thrown 45 Try 46 Dim result As Double = _ 47 SquareRoot(Convert.ToDouble(txtInput.Text)) 48 49 lblOutput.Text = result.ToString() 50 51 ' process invalid number format 52 Catch formatException As FormatException 53 MessageBox.Show(formatException.Message, _ 54 "Invalid Number Format", MessageBoxButtons.OK, _ 55 MessageBoxIcon.Error) 56 57 ' diplay MessageBox if negative number input 58 Catch negativeNumberException As NegativeNumberException 59 MessageBox.Show(negativeNumberException.Message, _ 60 "Invalid Operation", MessageBoxButtons.OK, _ 61 MessageBoxIcon.Error) 62 63 End Try 64 65 End Sub ' cmdSquareRoot_Click 66 67 End Class ' FrmSquareRoot SquareRootTest.vb
SquareRootTest.vb
Visual Basic enables user to specify whether arithmetic occurs in: Handling Overflows Visual Basic enables user to specify whether arithmetic occurs in: Checked context Default CLR throws OverflowException if overflow occurs Unchecked context Overflow produces truncated result