|Important||This document may not represent best practices for current development, links to downloads and other resources may no longer be valid. Current recommended version can be found here. ArchiveDisclaimer|
Structured Exception Handling
Visual Basic supports structured exception handling, which helps you create and maintain programs with robust, comprehensive error handlers. Structured exception handling is code designed to detect and respond to errors during execution by combining a control structure (similar to Select Case or While) with exceptions, protected blocks of code, and filters.
Using the Try...Catch...Finally statement, you can protect blocks of code that have the potential to raise errors. You can nest exception handlers, and the variables declared in each block will have local scope.
The Try...Catch...Finally Statement
The following code shows the structure of a Try...Catch...Finally statement:
Try ' Starts a structured exception handler. ' Place executable statements that may generate ' an exception in this block. Catch [optional filters] ' This code runs if the statements listed in ' the Try block fail and the filter on the Catch statement is true. [Additional Catch blocks] Finally ' This code always runs immediately before ' the Try statement exits. End Try ' Ends a structured exception handler.
The Try block of a Try...Catch...Finally exception handler contains the section of code you want your error handler to monitor. If an error occurs during execution of any of the code in this section, Visual Basic examines each Catch statement within the Try...Catch...Finally until it finds one whose condition matches that error. If one is found, control transfers to the first line of code in the Catch block. If no matching Catch statement is found, the search proceeds to the Catch statements of the outer Try...Catch...Finally block that contains the block in which the exception occurred. This process continues through the entire stack until a matching Catch block is found in the current procedure. If none is found, an error is produced.
The code in the Finally section always executes last, just before the error-handling block loses scope, regardless of whether the code in the Catch blocks has executed. Place cleanup code, such as that for closing files and releasing objects, in the Finally section.
Error Filtering in the Catch Block
Catch blocks allow three options for specific error filtering. In one, errors are filtered based on the class of the exception (in this case
ClassLoadException), as shown in the following code:
Try ' "Try" block. Catch e as ClassLoadException ' "Catch" block. Finally ' "Finally" block. End Try
ClassLoadException error occurs, the code within the specified Catch block is executed.
In the second error-filtering option, the Catch section can filter on any conditional expression. One common use of this form of Catch filter is to test for specific error numbers, as shown in the following code:
Try ' "Try" block. Catch When ErrNum = 5 'Type mismatch. ' "Catch" block. Finally ' "Finally" block. End Try
When Visual Basic finds the matching error handler, it executes the code within that handler, and then passes control to the Finally block.
Note When trying to find a Catch block to handle an exception, each block's handler is evaluated until a match is found. Since these handlers can be calls to functions, unexpected side effects may result; for example, such a call might change a public variable that is then used in the code of a different Catch block that ends up handling the exception.
As a third alternative, you can combine options one and two and use both for exception handling. Your Catch statements should move from most specific to least specific. A Catch block by itself will catch all exceptions derived from System.Exception, and therefore should always be placed as the last block before Finally.
Structured Exception Handler Example
The following example shows another simple error handler based on the Try...Catch...Finally statement:
Function GetStringsFromFile(ByVal FileName As String) As Collection Dim Strings As New Collection Dim Stream As System.IO.StreamReader = System.IO.File.OpenText(FileName) 'Open the file. Try While True ' Loop terminates with an EndOfStreamException ' error when end of stream is reached. Strings.Add(Stream.ReadLine()) End While Catch eos As System.IO.EndOfStreamException ' No action is necessary; end of stream has been reached. Catch IOExcep As System.IO.IOException ' Some kind of error occurred. Report error and clear collection. MsgBox(IOExcep.Message) Strings = Nothing Finally Stream.Close() ' Close the file. End Try Return Strings End Function
The Finally block is always run, regardless of any actions occurring in preceding Catch blocks. You cannot use Resume or Resume Next in structured exception handling.
Note Any exception other than the IOException class or the EndOfStreamException class is propagated back to the caller unhandled.