Visual Basic Concepts
Centralized Error Handling
When you add error-handling code to your applications, you'll quickly discover that you're handling the same errors over and over. With careful planning, you can reduce code size by writing a few procedures that your error-handling code can call to handle common error situations.
The following FileErrors function procedure shows a message appropriate to the error that occurred and, where possible, allows the user to choose a button to specify what action the program should take next. It then returns code to the procedure that called it. The value of the code indicates which action the program should take. Note that user-defined constants such as MnErrDeviceUnavailable must be defined somewhere (either globally, or at the module level of the module containing the procedure, or within the procedure itself). The constant vbExclamation is defined in the Visual Basic (VB) object library, and therefore does not need to be declared.
Function FileErrors () As Integer
Dim intMsgType As Integer, strMsg As String
Dim intResponse As Integer
' Return Value Meaning
' 0 Resume
' 1 Resume Next
' 2 Unrecoverable error
' 3 Unrecognized error
intMsgType = vbExclamation
Select Case Err.Number
Case MnErrDeviceUnavailable ' Error 68.
strMsg = "That device appears unavailable."
intMsgType = vbExclamation + 4
Case MnErrDiskNotReady ' Error 71.
strMsg = "Insert a disk in the drive "
strMsg = strMsg & "and close the door."
intMsgType = vbExclamation + 4
Case MnErrDeviceIO ' Error 57.
strMsg = "Internal disk error."
intMsgType = vbExclamation + 4
Case MnErrDiskFull ' Error 61.
strMsg = "Disk is full. Continue?"
intMsgType = vbExclamation + 3
' Error 64 & 52.
Case ErrBadFileName, ErrBadFileNameOrNumber
strMsg = "That filename is illegal."
intMsgType = vbExclamation + 4
Case ErrPathDoesNotExi ' Error 76.
strMsg = "That path doesn't exist."
intMsgType = vbExclamation + 4
Case ErrBadFileMode ' Error 54.
strMsg = "Can't open your file for that "
strMsg = strMsg & "type of access."
intMsgType = vbExclamation + 4
Case ErrFileAlreadyOpen ' Error 55.
strMsg = "This file is already open."
intMsgType = vbExclamation + 4
Case ErrInputPastEndOfFile ' Error 62.
strMsg = "This file has a nonstandard "
strMsg = strMsg & "end-of-file marker, "
strMsg = strMsg & "or an attempt was made "
strMsg = strMsg & "to read beyond "
strMsg = strMsg & "the end-of-file marker."
intMsgType = vbExclamation + 4
Case Else
FileErrors = 3
Exit Function
End Select
intResponse = MsgBox (strMsg, intMsgType, _
"Disk Error")
Select Case intRresponse
Case 1, 4 ' OK, Retry buttons.
FileErrors = 0
Case 5 ' Ignore button.
FileErrors = 1
Case 2, 3 ' Cancel, End buttons.
FileErrors = 2
Case Else
FileErrors = 3
End Select
End Function
This procedure handles common file and disk-related errors. If the error is not related to disk Input/Output, it returns the value 3. The procedure that calls this procedure should then either handle the error itself, regenerate the error with the Raise method, or call another procedure to handle it.
Note As you write larger applications, you'll find that you are using the same constants in several procedures in various forms and modules. Making those constants public and declaring them in a single standard module may better organize your code and save you from typing the same declarations repeatedly.
You can simplify error handling by calling the FileErrors procedure wherever you have a procedure that reads or writes to disk. For example, you've probably used applications that warn you if you attempt to replace an existing disk file. Conversely, when you try to open a file that doesn't exist, many applications warn you that the file does not exist and ask if you want to create it. In both instances, errors can occur when the application passes the file name to the operating system.
The following checking routine uses the value returned by the FileErrors procedure to decide what action to take in the event of a disk-related error.
Function ConfirmFile (FName As String, _
Operation As Integer) As Integer
' Parameters:
' Fname: File to be checked for and confirmed.
' Operation: Code for sequential file access mode
' (Output, Input, and so on).
' Note that the procedure works for binary and random
' access because messages are conditioned on Operation
' being <> to certain sequential modes.
' Return values:
' 1 Confirms operation will not cause a problem.
' 0 User decided not to go through with operation.
Const conSaveFile = 1, conLoadFile = 2
Const conReplaceFile = 1, conReadFile = 2
Const conAddToFile = 3, conRandomFile = 4
Const conBinaryFile = 5
Dim intConfirmation As Integer
Dim intAction As Integer
Dim intErrNum As Integer, varMsg As Variant
On Error GoTo ConfirmFileError ' Turn on the error
' trap.
FName = Dir(FName) ' See if the file exists.
On Error GoTo 0 ' Turn error trap off.
' If user is saving text to a file that already
' exists...
If FName <> "" And Operation = conReplaceFile Then
varMsg = "The file " & FName &
varMsg = varMsg & "already exists on " & vbCRLF
varMsg = varMsg & "disk. Saving the text box "
varMsg = varMsg & & vbCRLF
varMsg = varMsg & "contents to that file will "
varMsg = varMsg & "destroy the file's current "
varMsg = varMsg & "contents, " & vbCRLF _
varMsg = varMsg & "replacing them with the "
varMsg = varMsg & "text from the text box."
varMsg = varMsg & vbCRLF & vbCRLF
varMsg = varMsg & "Choose OK to replace file, "
varMsg = varMsg & "Cancel to stop."
intConfirmation = MsgBox(varMsg, 65, _
"File Message")
' If user wants to load text from a file that
' doesn't exist.
ElseIf FName = "" And Operation = conReadFile Then
varMsg = "The file " & FName
varMsg = varMsg & " doesn't exist." & vbCRLF
varMsg = varMsg & "Would you like to create and varMsg = varMsg & "then edit it?" & vbCRLF
varMsg = varMsg & vbCRLF & "Choose OK to "
varMsg = varMsg & "create file, Cancel to stop."
intConfirmation = MsgBox(varMsg, 65, _
"File Message")
' If FName doesn't exist, force procedure to return
' 0 by setting
' intConfirmation = 2.
ElseIf FName = "" Then
If Operation = conRandomFile Or _
Operation = conBinaryFile Then
intConfirmation = 2
End If
' If the file exists and operation isn't
' successful,
' intConfirmation = 0 and procedure returns 1.
End If
' If no box was displayed, intConfirmation = 0;
' if user chose OK, in either case,
' intConfirmation = 1 and ConfirmFile should
' return 1 to confirm that the intended operation
' is OK. If intConfirmation > 1, ConfirmFile should
' return 0, because user doesn't want to go through
' with the operation...
If intConfirmation > 1 Then
ConfirmFile = 0
Else
ConfirmFile = 1
If Confirmation = 1 Then
' User wants to create file.
If Operation = conLoadFile Then
' Assign conReplaceFile so caller will
' understand action that will be taken.
Operation = conReplaceFile
End If
' Return code confirming action to either
' replace existing file or create new one.
End If
End If
Exit Function
ConfirmFileError:
intAction = FileErrors
Select Case intAction
Case 0
Resume
Case 1
Resume Next
Case 2
Exit Function
Case Else
intErrNum = Err.Number
Err.Raise Number:=intErrNum
Err.Clear
End Select
End Function
The ConfirmFile procedure receives a specification for the file whose existence will be confirmed, plus information about which access mode will be used when an attempt is made to actually open the file. If a sequential file is to be saved (conReplaceFile), and a file is found that already has that name (and will therefore be overwritten), the user is prompted to confirm that overwriting the file is acceptable.
If a sequential file is to be opened (conReadFile) and the file is not found, the user is prompted to confirm that a new file should be created. If the file is being opened for random or binary access, its existence or nonexistence is either confirmed (return value 1) or refuted (return value 0). If an error occurs in the call to Dir, the FileErrors procedure is called to analyze the error and prompt the user for a reasonable course of action.