Let’s revisit what happens when errors arise in a console app that does not use exception handling. Figure 13.1 inputs two integers from the user, then divides the first integer by the second, using integer division to obtain an int
result. In this example, an exception is thrown (i.e., an exception occurs) when a method detects a problem and is unable to handle it.
In most of our examples, an app appears to run the same regardless of whether you run it by choosing Start Debugging or Start Without Debugging from the Debug menu. As we’ll discuss shortly, the example in Fig. 13.1 might cause exceptions, depending on the user’s input. For this example, we do not wish to debug the app; we simply want to see what happens when errors arise. For this reason, we executed this app with Debug > Start Without Debugging. If an exception occurs during execution, a dialog appears indicating that the app “has stopped working.” You can simply click Cancel or Close Program to terminate the app. An error message describing the exception that occurred is displayed in the program’s output. We formatted the error messages in Fig. 13.1 for readability. In the first sample execution, the program performs a successful division and runs to completion with no exceptions.
In the second sample execution, the user enters 0
as the denominator. Several lines of information are displayed in response to the invalid input. This information—known as a stack trace—includes the exception class’s name (System.DivideByZeroException
) in a
message indicating the problem that occurred and the path of execution that led to the exception, method by method. Stack traces help you debug a program. The first line of the error message specifies that a DivideByZeroException
occurred. When a program divides an integer by 0, the CLR throws a DivideByZeroException
(namespace System
). The text after the exception name, “Attempted to divide by zero
,” is an error message that indicates why this exception occurred. Division by zero is not allowed in integer arithmetic.2
Each “at
” line in a stack trace indicates a line of code in a particular method that was executing when the exception occurred. The “at
” line contains the namespace, class and method in which the exception occurred
DivideByZeroNoExceptionHandling.Main
the location and name of the file containing the code
C:UsersPaulDeitelDocumentsexamplesch13Fig13_01
DivideByZeroNoExceptionHandling
DivideByZeroNoExceptionHandling
DivideByZeroNoExceptionHandling.cs
and the line number
:line 18
where the exception occurred. (Class DivideByZeroNoExceptionHandling
is not declared in a namespace, so no namespace is displayed before the class name in this example’s stack traces.)
In this case, the stack trace indicates that the DivideByZeroException
occurred when
the program was executing line 18 of method Main
. The first “at
” line in the stack trace indicates the exception’s throw point—the initial point at which the exception occurred (i.e., line 18 in Main
). This information makes it easy for you to see which method call caused the exception. Subsequent “at
” lines in the stack trace specify what method calls were made to get to the throw point in the program.
In the third sample execution, the user enters the string
"hello
" as the denominator.
This causes a FormatException
, and another stack trace is displayed. Our earlier examples that read numeric values from the user assumed that the user would input an integer value, but a noninteger value could be entered. A FormatException
(namespace System
) occurs, for example, when int.Parse
receives a string
that does not represent a valid integer. Starting from the last “at
” line in the stack trace, we see that the exception was detected in line 15 of method Main
. The stack trace also shows the other methods that led to the exception being thrown:
Main
called Int32.Parse
—recall that int
is just an alias for Int32
,
Int32.Parse
called method Number.ParseInt32
, and
Number.ParseInt32
called Number.StringToNumber
.
The throw point occurred in Number.StringToNumber
, as indicated by the first “at
” line in the stack trace. Note that the stack trace’s actual text depends on your locale.
In the sample executions in Fig. 13.1, the program terminates when an unhandled exception occurs and a stack trace is displayed. This does not always happen—sometimes a program may continue executing even though an exception has occurred and a stack trace has been displayed. In such cases, the app may produce incorrect results. The next section demonstrates how to handle exceptions to enable the program to run to completion.