Unstructured error handling was the only method of error handling available in Visual Basic before .NET. Although it was simple to use, it didn't fulfill the hype that surrounded the announcement that the 2002 release of Visual Basic .NET would be an object-oriented programming system. Therefore, Microsoft also added structured error handling to the language, a method that uses standard objects to communicate errors, and error-handling code that is more tightly integrated with the code it monitors.
This form of error processing uses a multi-line Try...Catch...Finally statement to catch and handle errors.
Try ' ----- Add error-prone code here. Catch ex As Exception ' ----- Error-handling code here. Finally ' ----- Cleanup code goes here. End Try
The Try Clause
Try statements are designed to monitor smaller chunks of code. Although you could put all the source code for your procedure within the Try block, it's more common to put only the statements that are likely to generate errors within that section.
Try My.Computer.FileSystem.RenameFile(existingFile, newName) Catch...
"Safe" statements can remain outside of the Try portion of the Try...End Try statement. Exactly what constitutes a "safe" programming statement is topic of much debate, but there are two types of statements that are generally unsafe: (1) those statements that interact with external systems, such as disk files, network or hardware resources, or even large blocks of memory; and (2) those statements that could cause a variable or expression to exceed the designed limits of the data type for that variable or expression.
The Catch Clause
The Catch clause defines an error handler. As with unstructured error handling, you can include one global error handler in a Try statement, or you can include multiple handlers for different types of errors. Each handler includes its own Catch keyword.
Catch ex As ErrorClass
The ex identifier provides a variable name for the active error object that you can use within the Catch section. You can give it any name you wish; it can vary from Catch clause to Catch clause, but it doesn't have to.
ErrorClass identifies an exception class, a special class specifically designed to convey error information. The most generic exception class is System.Exception; other more specific exception classes derive from System.Exception. Because Try...End Try implements "object-oriented error processing," all the errors must be stored as objects. The .NET Framework includes many pre-defined exception classes already derived from System.Exception that you can use in your application. For instance, System.DivideByZeroException catches any errors that (obviously) stem from dividing a number by zero.
Try result = firstNumber / secondNumber Catch ex As System.DivideByZeroException MsgBox("Divide by zero error.") Catch ex As System.OverflowException MsgBox("Divide resulting in an overflow.") Catch ex As System.Exception MsgBox("Some other error occurred.") End Try
When an error occurs, your code tests the exception against each Catch clause until it finds a matching class. The Catch clauses are examined in order from top to bottom, so make sure you put the most general one last; if you put System.Exception first, no other Catch clauses in that Try block will ever trigger because every exception matches System.Exception. How many Catch clauses you include, or which exceptions they monitor, is up to you. If you leave out all Catch clauses completely, it will act somewhat like an On Error Resume Next statement, although if an error does occur, all remaining statements in the Try block will be skipped. Execution continues with the Finally block, and then with the code following the entire Try statement.
The Finally Clause
The Finally clause represents the "do this or die" part of your Try block. If an error occurs in your Try statement, the code in the Finally section will always be processed after the relevant Catch clause is complete. If no error occurs, the Finally block will still be processed before leaving the Try statement. If you issue a Return statement somewhere in your Try statement, the Finally block will still be processed before leaving the routine. (This is getting monotonous.) If you use the Exit Try statement to exit the Try block early, the Finally block is still executed. If, while your Try block is being processed, your boss announces that a free catered lunch is starting immediately in the big meeting room and everyone is welcome, the Finally code will also be processed, but you might not be there to see it.
Finally clauses are generally optional, so you need to include it only when you need it. The only time that Finally clauses are required is when you omit all Catch clauses in a Try statement.