Error Handling

  • Thread starter Thread starter JK
  • Start date Start date
J

JK

Is it recommended to include error handling on all Private Subs? When and/or
how often should I include error handling?

For example, is the following necessary?

Thanks,
Jason

Private Sub cmdAddNew_Click()
On Error GoTo Error_Handler

If vbYes = MsgBox("Add new record - are you sure?", vbYesNo + vbQuestion _
+ vbDefaultButton2, "<New Record>") Then
' Put focus on "key" control
' Make sure to save first
If Not SaveIt() Then Exit Sub
' Put myself in data entry mode
Me.DataEntry = True
Me.MailingName.SetFocus
End If

Exit_Procedure:
On Error Resume Next
Exit Sub

Error_Handler:
MsgBox "An error has occurred in this application." & Err & ", " & Error
& vbCrLf & vbCrLf & _
"Please contact your technical support person and report the problem.",
vbExclamation, "Error!"
ErrorLog Me.Name & "_cmdAddNew_Click", Err, Error
' Put the focus back in the database window
DoCmd.SelectObject acTable, "ErrorLog", True
Resume Exit_Procedure
End Sub
 
Pretty much YES. I take the approach that you never know what's going to
happen and better to have it in place and never needed that to need it and
not have it.

For the sake of coding, I also do a public sub that handles actually
displaying the error message as well as logging it in a table which makes
adding error handling much easier as it cuts down on the code actually
present in the other subs/functions as in...

Error_Form_Open:
Call ErrorHandler(Me.Name, Form_Open, Err.Number, Err.Description)
Exit Sub

Sub ErrorHandler(Optional strObjectName as string, strProcedure as String,
errNo as integer, errDescription as String)

[Do Something Here]

end sub
 
It's always good to have error handling, undoubtably. However, there are
two consideration we need to account for.

1) Not all errors needs to be handled; If you know there is going to be
an error, it actually may be appropriate to do check and drive the logic.

An obvious example is using DAO Recordset's NoMatch, BOF and EOF to
protect you from the errors we would get if we tried to do any Find or
Move methods. This is likely to be more efficient & cleaner than relying
on error handler to cover for you.

A less obvious example would be checking for file's existence. Instead
of trying to open a nonexistent file, we can just check FileLen() before
we try to open.

2) Sometime we may actually want to let the error drop to the calling
procedure.

For example:

Private Sub Foo()

On Error Goto HandleIt

Debug.Print Bar

HandleIt:
MsgBox Err.Number & " " & Err.Description

End Sub

Private Function Bar() As Double

Bar = 1/0

End Function

The error actually occurs in the function Bar, but the error handler in
Foo will catch it. In *some* circumstances, this may be what we want and
save us from writing several lines of error handlers. Of course, we lose
the granularity and detail of where the error actually occurred so it
may not be always appropriate.

I hope this is some food for thoughts.
 
Just a (somewhat picky) comment.

You're not resetting the error in sub Foo, which means it'll be propagated
to other routines as well.

You should always include Err.Clear or (perhaps better) Resume ... after
you've reported on the error.
 
Forgive if I'm mistaken, but my understanding was that if we declared
error handler, the error is automatically cleared once we reached the
end of procedure, even if we didn't explicitly clear/resume/whatever.

But I would have to agree with you in principle that it's best to be
explicit and clear/resume/whatever instead of letting it drop to the
floor, at least for the sake of documentation but also for clarity.

My test code:

Private Sub foo()

On Error GoTo handleit

Debug.Print bar()

Exit Sub
handleit:

Debug.Print Err.Number & " " & Err.Description
'The err is still nonzero, but will be cleared after End Sub.
End Sub

Private Function bar() As Double

bar = 1 / 0

End Function

Private Sub baz()

On Error GoTo handleit

Call foo

'The error has been cleared once we return from foo
Exit Sub
handleit:

Debug.Print Err.Number & " " & Err.Description
Err.Clear

End Sub


HTH.
 
My apologies. You're right.

I just checked the Help file on the Clear method, and it explicitly states

Use Clear to explicitly clear the Err object after an error has been
handled, for example, when you use deferred error handling with On Error
Resume Next.

The Clear method is called automatically whenever any of the following
statements is executed:

- Any type of Resume statement
- Exit Sub, Exit Function, Exit Property
- Any On Error statement
 
Back
Top