Visual Basic Classic Error Handling


Structured error handling using the Try block is a relatively recent innovation, appearing in the first versions of Visual Basic .NET. Visual Basic 6 and earlier versions used a more line-oriented syntax sometimes called Visual Basic Classic Error Handling. Although the Try block is generally preferred, you can still use classic error handling in your Visual Basic .NET applications. In fact, you can use both styles in the same program, although not in the same routine. The section “Structured versus Classic Error Handling” later in this chapter discusses the pros and cons of each.

A classic error handler begins with an On Error statement that tells Visual Basic what it should do if it encounters an error. This statement can take one of four forms: On Error GoTo line, On Error Resume Next, On Error GoTo 0, and On Error GoTo -1.

On Error GoTo line

After this statement, if Visual Basic encounters an error, it enters error-handling mode and jumps to the indicated line. The error handler that begins at the indicated line can take whatever action is appropriate.

The following code executes the statement On Error GoTo LoadPayrollError and then calls subroutine LoadPayrollFile. If that routine causes an error, Visual Basic jumps to the line labeled LoadPayrollError. The error-handler code displays an error message and exits the subroutine. The program then executes the statement On Error GoTo PrintPaychecksError and calls the PrintPaychecks routine. If that routine throws an error, the code starting at the PrintPaychecksError label executes. After it has finished its work, the routine uses an Exit Sub statement to end without falling into the error-handling code.

  Private Sub ProcessPayroll()     ' Load the payroll file.     On Error GoTo LoadPayrollError     LoadPayrollFile()     On Error GoTo PrintPaychecksError     ' Print paychecks.     PrintPaychecks()     ' We're done.     Exit Sub LoadPayrollError:     MessageBox.Show("Error loading the payroll file.")     Exit Sub PrintPaychecksError:     MessageBox.Show("Error printing paychecks.")     Exit Sub End Sub  

The program can leave error-handling mode using the statements Exit Sub, Exit Function, Resume, or Resume Next.

An Exit Sub or Exit Function statement makes the program immediately leave the routine in which the error occurred, and that’s the end of error-handling mode for this error.

The Resume statement makes the program resume execution with the statement that caused the error. If the problem has not been fixed, the error will occur again and the program may enter an infinite loop. You should use the Resume statement only if there is a chance that the error has been fixed. For example, if the program tries to read from a floppy disk and the drive is empty, the program could ask the user to insert the disk and then it could try to read the disk again.

The Resume Next statement makes the program resume execution with the statement after the one that caused the error. This statement is appropriate when the program cannot fix the problem but should continue anyway. For example, suppose that a program fails to read a value from a file. It might want to continue anyway so that it can close the file in the next statement.

On Error Resume Next

After this statement, if Visual Basic encounters an error, it skips the statement that caused the error and resumes execution with the following statement. If the program doesn’t care whether the statement completed, On Error Resume Next lets it continue without checking for errors.

If the program needs to take action when an error occurs, it can use the Err object to check for errors after each statement. For example, the following code uses the On Error Resume Next statement and then calls subroutine DoSomething. When the subroutine returns, the program checks the Err object’s Number property to see if an error occurred. If there is an error, the program displays a message and exits the subroutine. If subroutine DoSomething did not cause an error, the program calls subroutine DoSomethingElse and performs a similar check for errors.

  On Error Resume Next DoSomething() If Err.Number <> 0 Then     MessageBox.Show("Error in DoSomething")     Exit Sub End If DoSomethingElse() If Err.Number <> 0 Then     MessageBox.Show("Error in DoSomethingElse")     Exit Sub End If ...  

A program can also use this statement to check for different kinds of errors and take appropriate action. The following example takes no special action if there is no error. If Err.Number is 11, the program tries to divide by zero. In that case, the code sets variable X to a default value. If there is some other error, the program tells the user and exits the subroutine.

  ' Try to calculate X. On Error Resume Next X = CalculateValue() Select Case Err.Number     Case 0       ' No error. Do nothing.     Case 11      ' Divide by zero. Set a default value.         X = 1000     Case Else    ' Unexpected error. Tell the user.         MessageBox.Show("Error calculating X." & vbCrLf & Err.Description)         Exit Sub End Select ...  

On Error GoTo 0

The On Error GoTo 0 statement disables any active error handler. You should deactivate an error handler when it no longer applies to what the program is doing. The following code installs an error handler while it loads some data. When it is finished loading the data, it uses On Error GoTo 0 to deactivate the error handler before it performs other tasks.

  On Error GoTo LoadDataError ' Load the data. ... ' Done loading data. On Error GoTo 0     ...     Exit Sub LoadDataError:     MessageBox.Show("Error loading data." & vbCrLf & Err.Description)     Exit Sub End Sub  

Deactivating the error handler stops the program from taking inappropriate action for an error. In the previous example, it might confuse the user to say there was an error loading data when the program was doing something else. In other cases, the program might incorrectly try to fix problems that are not there if you leave an old error handler installed. For example, the program might ask the user to insert a floppy disk when it had already finished reading from the disk.

Deactivating old error handlers also lets the program fail if an unexpected error occurs. That lets developers discover and handle new types of failure, possibly by adding a new error handler.

On Error GoTo -1

The On Error GoTo -1 statement is very similar to On Error GoTo 0. It deactivates any active error handler. However, it also ends error-handling mode if it is running. The following code shows the difference. The program uses On Error GoTo DivideError1 to install an error handler and then executes a command that causes a divide-by-zero error.

In this code, the error-handler code uses On Error GoTo -1 to end error-handling mode and continue execution. It then calls On Error Resume Next to ignore errors and performs another calculation that divides by zero. Because the On Error Resume Next statement is in effect, the program ignores this error.

Next, the code uses On Error GoTo DivideError2 to install another error handler. It divides by zero again to jump to the error handler and enter error-handling mode.

This time the error handler uses the On Error GoTo 0 statement. This uninstalls the current error handler (On Error GoTo DivideError2), but does not end error-handling mode. The program then uses the On Error Resume Next statement. Unfortunately, this statement is ignored while the program is running in error-handling mode. If the program used a Resume statement to exit error-handling mode, this statement would then have an effect, but it does nothing until error-handling mode ends. Now, when the program divides by zero again, there is no active error handler, so the program crashes.

  Dim i As Integer Dim j As Integer = 0     On Error GoTo DivideError1     i = 1 \ j              ' This raises an error. DivideError1:              ' We enter error-handling mode here.     On Error GoTo -1       ' This ends error-handling mode.     On Error Resume Next   ' Ignore errors in the future.     i = 1 \ j              ' This error is ignored.     On Error GoTo DivideError2     i = 1 \ j              ' This raises an error. DivideError2:              ' We enter error-handling mode here.     On Error GoTo 0        ' This does NOT end error-handling mode.     On Error Resume Next   ' This statement doesn't     i = 1 \ j              ' This error is not caught and crashes the program. 

To avoid confusion, you should not use this style of error handling with error-handling code running through the body of a subroutine. Instead, place error-handling code at the end of the routine and use Exit Sub, Exit Function, Resume, or Resume Next to return to the routine’s main body of code. The On Error GoTo -1 statement is usually more confusing than it’s worth.

Error-Handling Mode

Undoubtedly the most confusing part of classic error handling is error-handling mode. The On Error GoTo line statement makes the program enter a special error-handling mode that remains in effect until the error handler calls Exit Sub, Exit Function, Resume, Resume Next, or On Error GoTo -1. While in error-handling mode, most other error-handling statements do not work as they normally do. Generally, their effects only take place when error-handling mode finally ends.

For example, consider the following code fragment. The program uses the statement On Error GoTo EquationError to install an error handler and then performs a calculation that divides by zero. The program jumps to the line labeled EquationError and enters error-handling mode. The error-handling code starts by executing the statement On Error Resume Next. Because the program is running in error-handling mode, this statement has no immediate effect. The program then performs another calculation that divides by zero. Because the code is already running in error-handling mode, it cannot jump to a new error handler, so the program crashes.

  Private i, j As Integer Private Sub PerformCalculation()     On Error GoTo EquationError     i = 1 \ j     Exit Sub EquationError:     On Error Resume Next     i = 2 \ j     Resume Next End Sub  

The previous example demonstrates one of the most common mistakes programmers make when working with error-handling mode. The error-handler code must be safe, or the program will crash (or at least the error will propagate up to the calling routine).

If you really need to perform risky operations in the error handler’s code, you should move that code into a subroutine. That routine can use its own error-handling code to protect itself from another error. The following example demonstrates this approach. The SetDefaultValue subroutine uses its own

  Private i, j As Integer Private Sub PerformCalculation()     On Error GoTo EquationError     i = 1 \ j     Exit Sub EquationError:     SetDefaultValue()     Resume Next End Sub Private Sub SetDefaultValue()     On Error Resume Next     i = 2 \ j End Sub  




Visual Basic 2005 with  .NET 3.0 Programmer's Reference
Visual Basic 2005 with .NET 3.0 Programmer's Reference
ISBN: 470137053
EAN: N/A
Year: 2007
Pages: 417

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net