Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Error Handler Displaying Function Name 1

Status
Not open for further replies.

dvannoy

MIS
May 4, 2001
2,765
US
I would like to know if it's possible to display the Name of a Public Sub in an error maessage.

I have several subs that are called on during certain transactions so, in my error handler I would like the name of the sub to appear in the error message.(if theres an error in that sub)

e.g. There Was an Error in "Public Sub"..

That way it will save time for me to trouble shoot.

any ideas would be appreciated

Thanks
 
If you really want to save time trouble shooting, you should implement line numbers and error handlers in all your subs/functions. This way you'll know exactly where the error occured. You can do this by using the Erl variable, which gives you access to the linenumber where the error occured (if you've implemented line numbers). You'll have to make a tool to process your codefiles first (for adding line numbers and, if you want, standard error handlers). Otherwise you'll get pretty annoyed by entering everything yourself...

But once you've done this, you only need to crossref the error number supplied with the (adjusted) code files and you'll know exactly where the error occured. This method is fabulous for "debugging" or some sort of beta-testing.
Greetings,
Rick
 
I use the following structure in my code. Each Sub and Function takes he following structure:
Code:
Private Sub SubName()
    On Error GoTo HandleError
Exit Sub
HandleError:
   ErrMessage vbNullString, FormName.SubName
   Resume Next
End Sub
The actual error handling code is in a module, but notice that the form/module/class name with the specific routine name is passed into the error handler as a parameter. Additional, there is another parameter that can be use to pass in some other value, that may be needed in certain circumstances.

The actual error handler is the following:
Code:
Public Sub ErrMessage(rStr_Err As String, rStr_Title As String)
   
   Dim lRst_Error          As ADODB.Error
   Dim lStr_Action         As String
   Dim lStr_NewLine        As String
   Dim lStr_Msg            As String
   Dim lStr_ErrDesc        As String
   Dim lStr_ErrParts()     As String
   Dim lInt_Idx            As Integer
   Dim lStr_ThisErr        As String
   
   lStr_Action = "ACTION" & vbTab & ":  " & "Please Notify System Administrator"
   lStr_NewLine = vbCrLf & vbTab & Space(3)
   
   lStr_Msg = "PROC " & vbTab & ":  " & rStr_Title & vbCrLf & vbCrLf & _
              "REFER" & vbTab & ":  " & rStr_Err & vbCrLf & vbCrLf & _
              "ERROR" & vbTab & ":  "
   
   If (gADO_Connect.Errors.count > 0) Then
      For Each lRst_Error In gADO_Connect.Errors
         With lRst_Error
            lStr_ErrDesc = vbNullString
            lStr_ErrParts = Split(.Description, "]")
            For lInt_Idx = 0 To UBound(lStr_ErrParts)
               lStr_ThisErr = Trim(lStr_ErrParts(lInt_Idx))
               If (Left(lStr_ThisErr, 1) = "[") Then
                  lStr_ThisErr = lStr_ThisErr & "]"
               End If
               lStr_ErrDesc = lStr_ErrDesc & lStr_ThisErr & lStr_NewLine
            Next lInt_Idx
            lStr_Msg = lStr_Msg & lStr_ErrDesc & lStr_NewLine & _
                       "(Source" & vbTab & vbTab & ": " & .Source & ")" & lStr_NewLine & _
                       "(SQL State" & vbTab & ": " & .SQLState & ")" & lStr_NewLine & _
                       "(NativeError" & vbTab & ": " & .NativeError & ")" & vbCrLf
         End With
      Next
      Set lRst_Error = Nothing
   Else
      With Err
         lStr_Msg = lStr_Msg & .Number & "  --  " & .Source & lStr_NewLine & .Description
      End With
   End If
   
   LogError "Error Occurred", lStr_Msg
   lStr_Msg = lStr_Msg & vbCrLf & vbCrLf & lStr_Action
   CenterTheCursor
   MsgBox lStr_Msg, vbExclamation + vbOKOnly, "An Error Has Occurred"

End Sub
The LogError function writes the error to a text file. Good Luck
--------------
As a circle of light increases so does the circumference of darkness around it. - Albert Einstein
 
Dam thats good!

Thanks alot, just what I was looking for.
 
CajunCenturion,

a couple of questions..

so on all your forms do you just have

On Error GoTo Error

Error:
SubName

and then your Subs start working??

CenterTheCursor is that a separate Function or am I missing something?

Also, where does the text file get written to ?

Thanks
 
Not quite - here is some actual code from a project (with the logic removed to protect the guilty) - here you can the actual names, and how they fit it. The first one comes from forms, so it uses the Me object, and the second comes from a module.
Code:
Private Sub cboPlatform_LostFocus(rInt_ComboID As Integer)

   On Error GoTo HandleError
  
Exit Sub

HandleError:

   ErrMessage "", (Me.Name & ".cboPlatform_LostFocus")
   Resume Next

End Sub 
'--------
Note that in this example, the input parameter to the function is passed thru to the error handler
Code:
'--------------
' from a module
Public Function ExecuteProcedure(rStr_ProcedureName As String) As Variant
   
   On Error GoTo HandleError
     
Exit Function

HandleError:

   ErrMessage rStr_ProcedureName, "DatabaseProcedures.ExecuteProcedure"
   Resume Next
    
End Function
The Function CenterTheCursor is a separate function and is not part of the Error Handler, it turns the cursor back to normal, and places it in the center of the screen, and slightly below the middle - attempting to pre-position over the ok button of the msgbox. It uses the SetCursorPos API which is declared as follows:
Code:
Public Declare Function SetCursorPos Lib "user32" (ByVal X As Long, ByVal y As Long) As Long

Public Sub CenterTheCursor()

   On Error GoTo HandleError
      
   Dim pLng_CursorLeft  As Long
   Dim pLng_CursorTop   As Long
      
   pLng_CursorLeft = (Screen.Width / 2) / Screen.TwipsPerPixelX
   pLng_CursorTop = ((Screen.Height / 2) + (600 * gDbl_HeightFactor)) / Screen.TwipsPerPixelY
   SetCursorPos pLng_CursorLeft, pLng_CursorTop
   Screen.MousePointer = vbNormal
   DoEvents
   
Exit Sub

HandleError:

   ErrMessage "", "GlobalModule.CenterTheCursor"
   Resume Next
End Sub
And if you're wondering - the statement
600 * gDbl_HeightFactor
is used to adjust the position for different screen resolutions with the height factor being the relative size of the actual screen to an 800x600 screen. Good Luck
--------------
As a circle of light increases so does the circumference of darkness around it. - Albert Einstein
 
Thank you for the kind words. Good Luck
--------------
As a circle of light increases so does the circumference of darkness around it. - Albert Einstein
 
Like LazyMe says, adding linenumbers to your code and using the Erl hidden variable in your error handler is a good way to locate a bug.

For a function name, I just hard-code it in my call to my centralized error handler. A trickier one is how to include the name of the program module. I define a constant at the top of each module that contains it's name, and then use it in my error handler call.
Code:
Private Const MODULENAME As String = "basMyModule"
:
:
ErrHandler:
  LogError(MODULENAME, "MyFunction", Erl, Err.Number, Err.Description)

Something else I do is not use an "Exit Sub" call. This is just a style thing, but I've never cared for it. Instead, I do this:
Code:
Public Function MyFunc() as Boolean
  
  Dim AdoConnect as ADODB.Connection
  MyFunc = False
  On Error Goto ErrHandler

  Set AdoConnect = new ADODB.Connection
  :
  :

  MyFunc = True  ' Indicate success
  Goto Cleanup

ErrHandler:
  LogError(MODULENAME, "MyFunc", Erl, Err.Number, Err.Description)
  ' Fall through into cleanup

Cleanup:
  If Not AdoConnect Is Nothing Then
    If AdoConnect.State = adOpen Then
      AdoConnect.Close
    End If
    Set AdoConnect = Nothing
  End If
End Function

The advantages of doing it this way is that you get a chance to clean up any resources in use, and that those resources get cleaned up whether or not an error occurs. There's only one copy of the cleanup code, too.

Hope this helps.
Chip H.
 
As you've probably noticed that with this kind of thing is that there is a lot of cutting and pasting of blocks of code.

One useful VB addin (that's free) I have come across is sliceanddice. It allows you to pre-define blocks of code and by right clicking in the IDE you can add the pre-defined lines of code into. It appears to do quite complex things to your code as well (if you want it to).

The website is
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top