Visual Basic Concepts

Inline Error Handling

You may be accustomed to programming in a language that doesn't raise exceptions — in other words, it doesn't interrupt your code's execution by generating exceptions when errors occur, but instead records errors for you to check later. The C programming language works in this manner, and you may sometimes find it convenient to follow this practice in your Visual Basic code.

When you check for errors immediately after each line that may cause an error, you are performing inline error handling. This topic explains the different approaches to inline error handling, including:

  • Writing functions and statements that return error numbers when an error occurs.

  • Raising a Visual Basic error in a procedure and handling the error in an inline error handler in the calling procedure.

  • Writing a function to return a Variant data type, and using the Variant to indicate to the calling procedure that an error occurred.

Returning Error Numbers

There are a number of ways to return error numbers. The simplest way is to create functions and statements that return an error number, instead of a value, if an error occurs. The following example shows how you can use this approach in the FileExists function example, which indicates whether or not a particular file exists.

Function FileExists (p As String) As Long
   If Dir (p) <> " " Then
      FileExists = conSuccess   ' Return a constant
                                 ' indicating the
   Else                           ' file exists.
      FileExists = conFailure   ' Return failure
                                 ' constant.
   End If
End Function

Dim ResultValue As Long
ResultValue = FileExists ("C:\Testfile.txt")
If ResultValue = conFailure Then
   .
   .   ' Handle the error.
   .
Else
   .
   .   ' Proceed with the program.
   .
End If

The key to inline error handling is to test for an error immediately after each statement or function call. In this manner, you can design a handler that anticipates exactly the sort of error that might arise and resolve it accordingly. This approach does not require that an actual run-time error arise. This becomes useful when working with API and other DLL procedures which do not raise Visual Basic exceptions. Instead, these procedures indicate an error condition, either in the return value, or in one of the arguments passed to the procedures; check the documentation for the procedure you are using to determine how these procedures indicate an error condition.

Handling Errors in the Calling Procedure

Another way to indicate an error condition is to raise a Visual Basic error in the procedure itself, and handle the error in an inline error handler in the calling procedure. The next example shows the same FileExists procedure, raising an error number if it is not successful. Before calling this function, the On Error Resume Next statement sets the values of the Err object properties when an error occurs, but without trying to execute an error-handling routine.

The On Error Resume Next statement is followed by error-handling code. This code can check the properties of the Err object to see if an error occurred. If Err.Number doesn't contain zero, an error has occurred, and the error-handling code can take the appropriate action based on the values of the Err object's properties.

Function FileExists (p As String)
   If Dir (p) <> " " Then
      Err.Raise conSuccess   ' Return a constant
                           ' indicating the
   Else                        'file exists.
      Err.Raise conFailure   ' Raise error number
                           ' conFailure.
   End If
End Function

Dim ResultValue As Long
On Error Resume Next
ResultValue = FileExists ("C:\Testfile.txt")
If Err.Number = conFailure Then
   .
   .   ' Handle the error.
   .
Else
   .
   .   ' Continue program.
   .
End If

The next example uses both the return value and one of the passed arguments to indicate whether or not an error condition resulted from the function call.

Function Power (X As Long, P As Integer, _
ByRef Result As Integer)As Long
   On Error GoTo ErrorHandler
   Result = x^P
   Exit Function
ErrorHandler:
   Power = conFailure
End Function

' Calls the Power function.
Dim lngReturnValue As Long, lngErrorMaybe As Long
lngErrorMaybe = Power (10, 2, lngReturnValue)
If lngErrorMaybe Then
   .
   .   ' Handle the error.
   .
Else
   .
   .   ' Continue program.
   .
End If

If the function was written simply to return either the result value or an error code, the resulting value might be in the range of error codes, and your calling procedure would not be able to distinguish them. By using both the return value and one of the passed arguments, your program can determine that the function call failed, and take appropriate action.

Using Variant Data Types

Another way to return inline error information is to take advantage of the Visual Basic Variant data type and some related functions. A Variant has a tag that indicates what type of data is contained in the variable, and it can be tagged as a Visual Basic error code. You can write a function to return a Variant, and use this tag to indicate to the calling procedure that an error has occurred.

The following example shows how the Power function can be written to return a Variant.

Function Power (X As Long, P As Integer) As Variant
   On Error GoTo ErrorHandler
   Power = x^P
   Exit Function

ErrorHandler:
   Power = CVErr(Err.Number)   ' Convert error code to
                              ' tagged Variant.
End Function

' Calls the Power function.
Dim varReturnValue As Variant
varReturnValue = Power (10, 2)
If IsError (varReturnValue) Then
   .
   .   ' Handle the error.
   .
Else
   .
   .   ' Continue program.
   .
End If