This documentation is archived and is not being maintained.

Structured Exception Handling Overview for Visual Basic 

Visual Basic supports structured exception handling, which you can use to 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.

' 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]
' 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 to be monitored for exceptions. If an error occurs during execution of this section, Visual Basic examines each Catch statement within the Try...Catch...Finally until it finds one with a condition that 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 no match 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. If you do not need to catch exceptions, but do need to clean up resources, consider using the Using statement rather than a Finally section. For more information, see Using Statement (Visual Basic).

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" block.
Catch e as ClassLoadException   
' "Catch" block.
' "Finally" block.
End Try

If a 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 type of Catch filter is to test for specific error numbers, as shown in the following code.

   ' "Try" block.
Catch When ErrNum = 5 'Type mismatch.
   ' "Catch" block.
   ' "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.


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, there may be unexpected side effects; for example, such a call can 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, using 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 Exception, and therefore should always be the last block before Finally.

Branching Out of Try…Catch Blocks

It is possible to branch from a Catch block back into the initial Try statement or the End Try statement, but it is not possible to branch into an enclosing Try…Catch block. This is illustrated here:

Try Catch Branching

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.

While True
' Loop terminates with an EndOfStreamException
' error when end of stream is reached. 
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.
Strings = Nothing
' 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.


In the preceding example, any exception other than the IOException class or the EndOfStreamException class is propagated back to the caller unhandled.

See Also