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!

Need to log errors using generic code 1

Status
Not open for further replies.

barryna

Programmer
Feb 15, 2002
111
US
Is there a way to (in code) pull what procedure you are currently in. I have around 100 different procedures in my project in which I have a error handler at the bottom of each. If an error occurs I wish to log that error into a log file (text file). I am using the following generic code right now but also need to pull the procedure i am currently in. I hope i don't have to resort to typing in the procedure i am in manually as a parameter for each of my procedures in my project.

Call LogErrors(Me.Name, Error, Err)
 
I am afraid that you will be typing in the name of the procedure. Check out the following for more information.

Thread222-444000
FAQ222-1694 Thanks and Good Luck!

zemp
 
Thanks for linking me to the thread i needed. It's too bad there isn't a better way of doing it.
 
Well, actually there is a way of making things a bit easier for you. I've been playing around with the VB IDE object model a while ago and I found it's quite easy to process VB projects. You can then have the kind of error checking you want automated. It's a bit of work, but once done it saves you a lot of trouble in the process of developing future projects in VB.


To give you a general idea of what I'm talking about, here's the procedure that actually inserts error handlers. Please forgive me, it's rather sloppy (was just playing around for testing and never got to cleaning it up) but it does work:


Private Function DoProcessMember(ByVal mbr As VBIDE.Member, ByVal cod As VBIDE.CodeModule, ByVal strFile As String, ByVal strName As String) As Boolean
'Processes the specified piece of code.
'
'mbr [IN]: The member to be processed (can be either a method or a property procedure).
'cod [IN]: The code module that contains this piece of code.
'strFile [IN]: The file name (excluding the path) of the code module.
'strName [IN]: The name of the module being processed.
'
'Returns True if succesfull, returns False if not.
Dim blnCase As Boolean
Dim intLoc As Long, n As Integer, intFirst As Integer, intLast As Integer
Dim strMsg As String, strLine As String

DoProcessMember = False 'Default to False.
On Error GoTo ErrHandler
If cod.Find("Declare Function " & mbr.Name, intLoc, 1, -1, -1, True, True) Then DoProcessMember = True: Exit Function
If cod.Find("Declare Sub " & mbr.Name, intLoc, 1, -1, -1, True, True) Then DoProcessMember = True: Exit Function
If mbr.Type = vbext_mt_Property Then 'Property procedures have two locations (Get and Let/Set), these have to processed both.
intLoc = 1
If cod.Find("Property Get " & mbr.Name, intLoc, 1, -1, -1, True, True) Then GoSub ProcessCode
intLoc = 1
If cod.Find("Property Let " & mbr.Name, intLoc, 1, 1, -1, -1, True, True) Then GoSub ProcessCode
intLoc = 1
If cod.Find("Property Set " & mbr.Name, intLoc, 1, 1, -1, -1, True, True) Then GoSub ProcessCode
Else 'Methods have but one.
intLoc = mbr.CodeLocation
GoSub ProcessCode
End If
DoProcessMember = True 'All went well.
Exit Function
ProcessCode:
intLoc = intLoc + 1: intFirst = intLoc 'The location of the first line after the procedure declaration.
cod.InsertLines intLoc, Chr$(9) & "On Error GoTo SysErr" & mbr.Name 'Insert a reference to the standard error handler of this procedure here.
If frmError.chkCall.Value = 1 Then cod.InsertLines intLoc, Chr$(9) & "UpdateCallStack " & Chr$(34) & strName & "." & mbr.Name & Chr$(34)
If mbr.Type = vbext_mt_Property Then 'It's a property procedure.
cod.Find "End Property", intLoc, 1, -1, -1, True, True
strLine = "Exit Property"
AfterError:
Else
intLoc = 1
If cod.Find("Function " & mbr.Name, intLoc, 1, -1, -1, True, True) Then 'It's a function, and we have the location of the function declaration now too.
cod.Find "End Function", intLoc, 1, -1, -1, True, True 'Find the end of the function.
strLine = "Exit Function"
Else 'It's a sub
cod.Find "Sub " & mbr.Name, intLoc, 1, -1, -1, True, True 'Find the location of the sub declaration.
cod.Find "End Sub", intLoc, 1, -1, -1, True, True 'Now find the end of the sub.
strLine = "Exit Sub"
End If
End If
intLast = intLoc + 3 'This is where the call to the error handler will be placed.
cod.InsertLines intLoc, Chr$(9) & "GlobalSysErrorHandler " & Chr$(34) & strFile & Chr$(34) & ", " & Chr$(34) & mbr.Name & Chr$(34) & ", Erl, Err.Number, Err.Description, " & Chr$(34) & gstrVersion & Chr$(34) & ", " & Chr$(34) & Trim$(frmError.txtLog.Text) & Chr$(34) 'The call to the global error handler.
cod.InsertLines intLoc, "SysErr" & mbr.Name & ":" 'The label of the local error handler.
cod.InsertLines intLoc, Chr$(9) & strLine 'Exit sub/fuction/property must be inserted before the local error handler !
blnCase = False
For n = intFirst To intLast - 1 'Now process each line in the member.
If Not blnCase Then 'The previous line was a 'Select Case' statement, this means that the next line is not allowed to have a label (or line number).
If DoCheckLine(cod.Lines(n, 1), blnCase) Then 'Check if the line needs processing.
glngLineNr = glngLineNr + 1 'Add a line number and replace any 'on error goto 0's'
cod.ReplaceLine n, Trim$(glngLineNr) & Space$(6 - Len(Trim$(glngLineNr))) & Chr$(9) & Replace(cod.Lines(n, 1), "On Error GoTo 0", "On Error GoTo SysErr" & mbr.Name)
End If
Else
blnCase = False
End If
Next n
Return
ErrHandler:
If Err.Number = 35 Then Resume AfterError
strMsg = "An error occured while processing the project files:" & Chr$(13)
strMsg = strMsg & Err.Description & " (" & Trim$(Err.Number) & ")."
MsgBox strMsg, vbCritical, "Automatic Error Handler:"
End Function


Greetings,
Rick
 
[b[LuckyMe[/b] has at least the general concept, but i think it can be even easier than what he is showing. It has been a while, and I do not have the code 'handy', but generically evey object in VB is just a text file. You can easily 'see' this by opening word pad and browsing to any VB object and opening it.

If it is a form, you will see some generic header info folowed by the controls and their customized attributes (where defaults are used VB doesn't store them) after the controls, the code associated with the form is shown.

If the object is a module, you will see a somewhat different "header", again followed by the procedures.

Since it is trivially easy to open these objects AS TEXT files, it is also trivially easy to modify them -AS TEXT FILES. So, to insert the assignment of a procedure's name into the procedure, you simply write a seperate procedure which examines each object in the vb projecct. For each instance of a procedure declaration, add the assignment statement immediatly following that declaration. In a similar manner, error handlers may be added.

About the only tricks involved here is the 'recognition' of the procedure declaration lines and that you generally would want to write the object files to a different location than they are read from.

Post processing is to simply copy the revised object files back to the original location. I have found that saving the original object files to a backup location is helpful, after all every attempt is not an un-qualified success.

MichaelRed
m.red@att.net

Searching for employment in all the wrong places
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top