views:

1812

answers:

4

When an error occurs in a function, I'd like to know the sequence of events that lead up to it, especially when that function is called from a dozen different places. Is there any way to retrieve the call stack in VB6, or do I have to do it the hard way (e.g., log entries in every function and error handler, etc.)?

+5  A: 

I'm pretty sure you have to do it the hard way. At a previous job of mine, we had a very elegant error handling process for VB6 with DCOM components. However, it was a lot redundant code that had to be added to every method, so much that we had home-grown tools to insert it all for you.

I can't provide too much insight on its implementation (both because I've forgotten most of it and there's a chance they may consider it a trade secret). One thing that does stand out was that the method name couldn't be derived at run-time so it was added as a string variable (some developers would copy-paste instead of using the tool and it would lead to error stacks that lied...).

HTH

Austin Salonen
This is the only way I know to do it. As suggested below, MZTools can help. In your template for your error handler, if you're going to propagate the error, append your current function/sub to the err.source.
Matthew Cole
I'm convinced there is no way to do what I asked, so I'll accept this answer.
raven
+2  A: 

The hard, manual way is pretty much the only way. If you check out this question, someone suggested a tool called MZTools that will do much of the grunt work for you.

Darrel Miller
I've been using MZTools for years and I agree that it is a great tool. However, I was looking for an alternative to the "poor man's stack trace". I didn't think there was one, but I thought it couldn't hurt to ask here.
raven
A: 

Compuware (or was it Numega at the time) DevStudio for Visual Basic 6 used to do this. The way was by adding adding instrumenation to every call that called a very small snippet that added to the code stack. On any error it dumped out that callstack, and then did things like mail or post to a webserver all the debuging information. Adding and removing the instrumentation was a potentially lethal operation (especially back then, when we were using VSS as our source control), but if it worked, it work well.

As Darrel pointed out, you could add something very simlar by using MZTools and setting up a template. It's a lot of working, and is probably more effeort than the reward would be but if you have very difficult to track down bugs, it might help).

Kris Erickson
+2  A: 

You do have to do it the hard way, but it's not really all that hard... Seriously, once you've written the template once, it's a quick copy/paste/modify to match the function name in the Err.Raise statement to the actual function name.

Private Function DoSomething(ByVal Arg as String)

    On Error GoTo Handler

    Dim ThisVar as String
    Dim ThatVar as Long

    ' Code here to implement DoSomething...

    Exit Function

Handler:
    Err.Raise Err.Number, , "MiscFunctions.DoSomething: " & Err.Description

End Function

When you have nested calls, this unwinds as each routine hits its Handler and adds its name to the error description. At the top level function, you get a "call stack" showing the list of routines that were called, and the error number and description of the error that actually occurred. It's not perfect, in that you don't get line numbers, but I've found that you don't usually need them to find your way to the problem. (And if you really want line numbers, you can put them in the function and reference them in the Err.Raise statement using the Erl variable. Without line numbers, that just returns 0.)

Also, note that within the function itself, you can raise your own errors with the values of interesting variables in the message like so:

Err.Raise PCLOADLETTER_ERRNUM, , "PC Load Letter error on Printer """ & PrinterName & """"

(The syntax highlighting looks wonky in the preview... I wonder how will it look when posted?)

JeffK
upvoted for pc load letter
rpetrich