Logger Frequently
Asked Questions
[ Home ] [ Up ] [ Download Logger ] [ FAQ ]
Why are no error
messages being written to the log file?
Do
I need to include a reference to "Babbacombe Logger VB Add-In" in my projects?
I'm adding handlers to a very
large project and the logger stopped writing them half way through.
Should I include full stack tracing?
Why has a blank
error message, number zero, been logged?
How does
the logger decide whether it needs to add an error trap?
I've got a thousand instances of a
class all running at the same time. How do I tell which one is generating an error?
You probably haven't initialised the error handler correctly. When your application
starts up you need to create an instance of a BabErrorManager object, set its CallingApp
property and ensure that it doesn't get terminated before the application terminates. If
the object does terminate the error handler dll can be unloaded from memory and it will
then lose track of where it should write errors to. For some examples of how to fix this
look up BabErrorManager in the Help.
No. You only need to include a reference to "Babbacombe Run-time Error
Handler". If you include one to the add-in you might find it being added to your
distribution.
Make sure Auto Save is ticked. There is a bug in the VB5 IDE which causes it to lose
new lines of text if it has too much unsaved source in memory.
This is a trade off between the detail of the information you get when an error
happens, against the size, and to a much smaller extent speed, of your executables. Errors
get trapped exactly the same whether you include stack traces or not, but if you do not
you only know the name of the routine where the error was trapped, and not the one where
the error actually happened. If you want to add less code, and are happy with not getting
all the extra detail, you can switch off stack tracing. You can, of course, switch off
stack tracing for some components and leave it on for others.
If you write good OOP code, and build object hierarchies with lots of inheritance, much
of your code will consist of one line routines which simply pass the call through to
another object. If you don't think you need to identify calls to these one-liners you can
tell the logger to Skip One Line Routines. It will still add error traps to one line
routines which need them but won't bother adding any code if it would only put a stack
trace call in.
There are several possibilities. One is that you have accidentally edited the code
added to a routine and removed the Exit statement just before the Trap label. If not, it
is possible that the Err object has been cleared before the error handler has been called.
There are several statements which clear the Err object, including On Error and Exit
<routine>. If an error occurs, and is trapped in a calling routine, VB doesn't
necessarily jump straight to the Trap label and continue executing from there. If the
routine where the error occurs (or one between it and the error trap) has created an
instance of an object, and stored it in a local variable, the object could be terminated
before the error handler is called. If this happens, and it has terminate code in it, this
could execute a statement which clears the Err object.
There is no easy way to anticipate this error. If you know which object termination is
causing the problem you could remove any error traps from it (if they were created by the
logger) by adding a '$INT directive immediately before it, but you must first be confident
that no errors could occur in the termination (and, of course, you must do the same to any
routines which the Terminate handler could call). If you know which routine is creating
the object you could instead add an error trap to that routine, by adding a '$EXT
directive before it, so that the handler is called while the object still exists. This is
almost always a better solution, but to fix this problem you really need to be able to
reproduce the error.
Just to make anticipating it a little more difficult, the order in which the various
actions - terminating local objects and jumping to the error handler - occur seems to
depend on the threading model of the application. I have seen this problem occur in a
multithreaded app, and cured it temporarily by making it single threaded.
From version 1.7.0 the logger inserts an extra call before setting the error trap in
Class_Terminate events which stores any error information before the trap can clear it.
This should prevent this problem occurring.
It looks at each routine header as it gets to it, and runs through a series of tests.
When reading the declarations section it stores a list of any interfaces implemented by
the module. If it decides the routine could be called from outside the application (an
External entry point) it gives it an error trap, and if it decides that it can only be
called from inside the application (an Internal entry point) it does not. Routines which
are called from the VB run-time, such as Terminate routines are considered External
because errors which reach the VB run-time are trapped by it rather than being passed on
to handlers in VB code.
- If the routine name is Main it assumes it is the program's Sub Main and decides it is
External.
- If the module is a Public class which is exported from an EXE server it first checks
whether the routine is Public, and if it is it decides it is External. Otherwise it looks
for an underscore in its name. If it finds one (and only one) it checks whether it is part
of an interface implementation. If it is, it decides it is External (it might not be but
there isn't any way of telling for certain). If neither of these conditions is met it
carries on thinking about it.
- If it is a Function or a Property it can only be called from somewhere inside the same
app and so it decides it is Internal. (Remember, it has already eliminated the possibility
that it is exported from an EXE server, and calls exported from a DLL are considered
Internal because they are in the same app).
- If the routine is Public it checks whether it is part of the explicit external callbacks
list (stored in ExternalCallbacks.txt in the logger directory). If so, it decides it is
external. If the routine has
- If the routine name doesn't contain one underscore, or is Public or Friend, it isn't an
event, so it decides it is Internal.
- If the first part of the routine name (up to the underscore) is the name of an
implemented interface it decides it is Internal, unless the second part of the name is in
the external callbacks list, in which case it decides it is External.
- Otherwise, it looks just like an Event, and is considered External.
You use the ID directive. When you create a lot of objects like that there is almost
always some string that you can use to identify each one. For example, if the objects
represent webpages you have seen the identifier would be the URL. If they represent
employees it could be their name or social security number.
Make sure the logger's code has been removed from the module, and add
'$ID Name
to the declarations section of the class module, where Name is the string variable
containing the identifier for this object. When you tell the logger to add its code it
will now add Name (or whatever your variable is called) to the end of the list of
parameters to calls to its routines. You should use a string variable for this (although a
numeric should always work), and it should be a variable and not a Property Get (because
that could, in theory, fire off another error, could mess around with the stack to no
useful purpose, and could even clear the Err object). This doesn't just work in class
modules - it can also be useful for forms and controls.
[ Home ] [ Up ] [ Download Logger ] [ FAQ ] |