10.10.1.2 Catch Blocks
If an exception occurs while processing the Try block, each Catch statement is examined in textual order to determine if it handles the exception. The identifier specified in a Catch clause represents the exception that has been thrown. If the identifier contains an As clause, then the identifier is considered to be declared within the Catch block's local declaration space. Otherwise, the identifier must be a local variable (not a static variable) that was defined in a containing block.
A Catch clause with no identifier will catch all exceptions derived from System.Exception. A Catch clause with an identifier will only catch exceptions whose types are the same as or derived from the type of the identifier. The type must be System.Exception or a type derived from System.Exception. A Catch clause with a When clause will only catch exceptions when the expression evaluates to True; the type of the expression must be implicitly convertible to Boolean. A When clause is only applied after checking the type of the exception, and the expression may refer to the identifier representing the exception, as this example demonstrates:
Imports System Module Test Sub Main() Dim i As Integer = 5 Try Throw New ArgumentException() Catch e As OverflowException When i = 5 Console.WriteLine("First handler") Catch e As ArgumentException When i = 4 Console.WriteLine("Second handler") Catch When i = 5 Console.WriteLine("Third handler") End Try End Sub End Module
This example prints:
If a Catch clause handles the exception, execution transfers to the Catch block. At the end of the Catch block, execution transfers to the first statement following the Try statement. The Try statement will not handle any exceptions thrown in a Catch block. If no Catch clause handles the exception, execution transfers to a location determined by the system.
It is invalid to explicitly transfer execution into a Catch block.
A catch block can branch into a try block in the same Try statement, but only if there is no intervening nested Try statements. For example, the following produces a compile-time error:
Module Test Sub Main() Try Throw New Exception() out: Catch e As Exception Try Throw New Exception() Catch eInner As Exception ' Error: Not directly contained. Goto out End Try End Try End Sub End Module
CatchStatement ::= Catch [ Identifier As TypeName ] [ When BooleanExpression ] StatementTerminator [ Block ]