Just a quick note today. I wanted to add the call stack to my error log messages for my client app. That way I could see the full set of calls that was causing the error and it would help me debug better.
For example, if I pass bad SQL to my SQL Executing function, I was just getting the error logged from that function saying it didn’t work and what the error message was. It was not showing me the form the user was calling it from.
Check out this info I was able to build using vbWatchdog’s Callstack object:
vbW: Error #2501 - The OpenForm action was canceled.
---> utility_functions.ECI_OpenForm: Line 2, VBA: DoCmd.OpenForm Formname, View, FilterName, WhereCondition, DataMode, WindowMode, OpenArgs
---> ECI_ApScreenController.CheckForDifferencesFromPo: Line 1, VBA: ECI_OpenForm "ap_check_for_po_modifications", acNormal, , , , acDialog
---> ECI_ApScreenController.InitializeFormForEditing: Line 16, VBA: CheckForDifferencesFromPo
---> ECI_ApScreenController.Mode: Line 7, VBA: InitializeFormForEditing
---> ECI_ApScreenController.ResetMode: Line 4, VBA: Mode = "Edit" Else
---> ECI_ApScreenController.evtfrm_Current: Line 1, VBA: ResetMode
---> utility_functions.ECI_OpenForm: Line 2, VBA: DoCmd.OpenForm Formname, View, FilterName, WhereCondition, DataMode, WindowMode, OpenArgs
---> Form_order_invoice_inquiry.order_choice_AfterUpdate: Line 8, VBA: ECI_OpenForm "order_invoice", , , "order_invoice_id = " & lngOI_ID
This is pretty sweet. I used the example from the vbWatchdog documentation to build this little loop that created the above output:
' -------
' Added variable and putlog to app to get more info logged on errors.
strCallStack = "vbW: Error #" & CStr(ErrEx.Number) & " - " & CStr(ErrEx.Description) & vbLf
With ErrEx.Callstack
.FirstLevel
Do
strCallStack = strCallStack & "---> " & .ModuleName & "." & .ProcedureName & ": Line " & _
.LineNumber & ", VBA: " & .LineCode & vbLf
Loop While .NextLevel
End With
AJS.putLog strCallStack
' -------
Jonathan, also consider expanding the log to include the variables information in each stack frame, as that extra information can be very useful and is easily available via vbWatchdog. Though naturally this may increase log file size significantly so I often give an ‘advanced logging’ option so that it can be toggled if necessary by the client if we need further information.
Our apps usually store log info in the database. I guess the main drawback to that is that the database may not be available, causing an error that will never get logged. Maybe I should make sure I log those errors to a file. 🙂