Visual Basic

Tip 9: Trace the stack.

As you saw in the log file in Listing 1-3, we dump the VBA call stack when we hit an unexpected error because it can be useful for working out later what went wrong and why. We build an internal representation of VBA's stack (because VBA's stack is not actually available-shame), using two fundamental routines: TrTraceIn and TrTraceOut. Here they are in a typical routine:

Public Sub Testing()
  ' Set up general error handler.
  On Error GoTo Error_General_Testing:
      Const sProcSig = MODULE & " General.Testing"
      Call TrTraceIn(sProcSig)
      ' ========== Body Code Starts ==========
      .
      .
      .
      ' ========== Body Code Ends ==========
      Call TrTraceOut(sProcSig)
      Exit Sub
  ' Error handler.
  Error_General_Testing:
      .
      .
      .
  End Sub

These routines are inserted by hand or by using the same internal tool I mentioned earlier in Tip 2 that adds line numbers to code. Notice that sProcSig is being passed into these routines so that the stack can be built containing the name of the module and the routine.

The stack frame object we use internally (not shown here) uses a Visual Basic collection with a class wrapper for its implementation. The class name we use is CStackFrame. As a prefix, C means class, and its single instance is named oStackFrame. We drop the o prefix if we're replacing a standard class such as Err or App.

Tip 10: Use a ROOS (Resource Only OLE Server).

A basic ROOS (pronounced "ruse") is a little like a string table resource except that it runs in-process or out-of-process as an Automation server. A ROOS provides a structured interface to a set of objects and properties that enables us to build more flexible error handling routines.

For example, the ROOS holds a project's error constants (or rather the values mapped to the symbols used in the code that are resolved from the object's type library). The ROOS also holds a set of string resources that hold the actual error text for a given error and the methods used to load and process errors at run time. To change the language used in error reports or perhaps the vocabulary being used (for example, user vs. programmer), simply use a different ROOS. (No more DLLs with weird names!)