• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 783
  • Last Modified:

How to trap VBA errors without error handlers

I would like to trap all VBE errors (even when a procedure has no error handler). I didn't even know this was possible until I read this webpage: http://www.everythingaccess.com/vbwatchdog/howitworks.htm
0
Milewskp
Asked:
Milewskp
  • 5
  • 5
  • 5
  • +1
5 Solutions
 
Jim Dettman (Microsoft MVP/ EE MVE)PresidentCommented:
From the on-line help in Access "Elements of Run-time error handling":

"Handling Errors in Nested Procedures

When an error occurs in a nested procedure that doesn't have an enabled error handler, Visual Basic searches backward through the calls list for an enabled error handler in another procedure, rather than simply halting execution. This provides your code with an opportunity to correct the error within another procedure. For example, suppose Procedure A calls Procedure B, and Procedure B calls Procedure C. If an error occurs in Procedure C and there's no enabled error handler, Visual Basic checks Procedure B, then Procedure A, for an enabled error handler. If one exists, execution passes to that error handler. If not, execution halts and an error message is displayed.

Visual Basic also searches backward through the calls list for an enabled error handler when an error occurs within an active error handler. You can force Visual Basic to search backward through the calls list by raising an error within an active error handler with the Raise method of the Err object. This is useful for handling errors that you don't anticipate within an error handler. If an unanticipated error occurs, and you regenerate that error within the error handler, then execution passes back up the calls list to find another error handler, which may be set up to handle the error.

For example, suppose Procedure C has an enabled error handler, but the error handler doesn't correct for the error that has occurred. Once the error handler has checked for all the errors that you've anticipated, it can regenerate the original error. Execution then passes back up the calls list to the error handler in Procedure B, if one exists, providing an opportunity for this error handler to correct the error. If no error handler exists in Procedure B, or if it fails to correct for the error and regenerates it again, then execution passes to the error handler in Procedure A, assuming one exists.

To illustrate this concept in another way, suppose that you have a nested procedure that includes error handling for a type mismatch error, an error which you've anticipated. At some point, a division-by-zero error, which you haven't anticipated, occurs within Procedure C. If you've included a statement to regenerate the original error, then execution passes back up the calls list to another enabled error handler, if one exists. If you've corrected for a division-by-zero error in another procedure in the calls list, then the error will be corrected. If your code doesn't regenerate the error, then the procedure continues to run without correcting the division-by-zero error. This in turn may cause other errors within the set of nested procedures.

In summary, Visual Basic searches back up the calls list for an enabled error handler if:

·      An error occurs in a procedure that doesn't include an enabled error handler.
·      An error occurs within an active error handler. If you use the Raise method of the Err object to raise an error, you can force Visual Basic to search backward through the calls list for an enabled error handler.
"

  and that pretty much spells it out.  You only need one error handler enabled for all of your code BUT that means that you'll back up the call stack chain with every procedure that doesn't have one, which in most cases, I've always found undesireable.  I put an error handler in just about every procedure.

Hope that answers the question.
JimD.
0
 
MilewskpAuthor Commented:
Thanks Jim,
That's useful information. What I was looking for, though, is what they have in vbwathdog (as described @ http://www.everythingaccess.com/vbwatchdog/howitworks.htm).

However, your answer made me realize that such a feature is useless without being able to access the callstack, which you've already told me is not a feature of VBA: http://www.experts-exchange.com/Microsoft/Development/MS_Access/Q_26621434.html?cid=1575#a34156185)
0
 
Jeffrey CoachmanMIS LiasonCommented:
I have seen quite a few of these "Global" error handlers.
Interesting,?, Yes, Useful?...Debatable
;-)

But as Jim states (at least for VBA) the standard "Best Practices" recommended by all documentation, MVP's, ...etc, is to put Error handling in all of your subs.
See rule #5 here:
http://www.mvps.org/access/tencommandments.htm

Here is another great link on Error Handling (Includes a section on Global Error handlers as well)
http://www.fmsinc.com/tpapers/vbacode/Debug.asp

JeffCoachman
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
Jim Dettman (Microsoft MVP/ EE MVE)PresidentCommented:
<<That's useful information. What I was looking for, though, is what they have in vbwathdog (as described @ http://www.everythingaccess.com/vbwatchdog/howitworks.htm). >>

 Sorry, I didn't go through all their docs.  Until now a "Global Error Handler" says and meant something different then what they've done.  Until now, it meant a error handler that catches all the errors if a local error handler is not in place and generally it was a single procedure that deals with errors.

  But now because these folks have gotten into the guts of VBA it's something a little different.  What their doing is short circuiting the error handling and allowing their class to handle errors before the normal VBA error logic takes place.

 That means without defining error handlers in every procedure, you can still have one centralized procedure and it will get called at the procedure level as if the procedure did have an error handler.  So it's truely global.

  However without getting into the guts of VBA, you can't do that on your own.

JimD.
0
 
DatabaseMX (Joe Anderson - Microsoft MVP, Access and Data Platform)Commented:
@Milewskp,
You really should be asking Wayne these questions.  However, before you do ... it's all pretty well spelled in the help file for Watchdog, was well as additional information on the 'native code' concept.

This posted above:

"What their doing is short circuiting the error handling and allowing their class to handle errors before the normal VBA error logic takes place. "

... pretty much sums it  up.  As a Beta tester on Watchdog, may I suggest 'using' the product as opposed to re-inventing what was done, if that is what you are hoping to do ... because it is *not trivial*.

mx
0
 
MilewskpAuthor Commented:
Hi mx,
<it's all pretty well spelled in the help file for Watchdog>
I looked, but couldn't find it.
0
 
DatabaseMX (Joe Anderson - Microsoft MVP, Access and Data Platform)Commented:
Did you download the demo ?

0
 
DatabaseMX (Joe Anderson - Microsoft MVP, Access and Data Platform)Commented:
0
 
MilewskpAuthor Commented:
Hi mx,
It seems to me that the demo and the link tells us what it does, but I'm interested in how, as Jim says, they short circuit the error handling and allow their class to handle errors before the normal VBA error logic takes place.  Am I missing something?
0
 
Jim Dettman (Microsoft MVP/ EE MVE)PresidentCommented:
<<It seems to me that the demo and the link tells us what it does, but I'm interested in how, as Jim says, they short circuit the error handling and allow their class to handle errors before the normal VBA error logic takes place.  Am I missing something? >>

  They are not going to tell you that.  As MX said, it's not a trival task and if they told you, they'd be giving away trade secrets.  You might be able to glean something from the class module (I haven't looked at it yet), but I would bet you would not get everything you need to know.

 Let's face it, they have hundreds if not thousands of hours in this thing so their not going to spell out in detail how it works.   Just as Microsoft has never fully documented JET.

  If you want to know, you'll have to figure it out for yourself just as they did.

JimD.
0
 
Jim Dettman (Microsoft MVP/ EE MVE)PresidentCommented:
 I just looked at the demo and it was as I thought; gives you part of the picture but not the whole thing.

  What they've done is build a COM object in memory on the fly.   The COM object has the functions for the classes and it hooks the interupt table for the VBA error trapping.  A "hook" is a re-direction of the thread execution to another address.    

 So now when an error occurs, rather then going to the VBA error handling code, it points to this com object they've created.  The COM object can then do what it wants and then either stop there or continue by calling the original code.

  In this case, that's the difference between Enabled and not.  If the global error handling is not enabled, the COM object does nothing and simply calls the original code.

  However if it is enabled, the code in the COM object knows where in memory to fetch the various items it needs (ie. call stack, variables, etc).  

  They've dug into VBA at an extremely low level.  The knowledge to do so as the web site points out was learned in the process of learning how to decompiling MDE's.

JimD.

0
 
Jim Dettman (Microsoft MVP/ EE MVE)PresidentCommented:
BTW, if you want a little more detail on how Wayne achieved this, look at:

http://www.everythingaccess.com/tutorials.asp?ID=A-new-method-for-disabling-the-Mouse-Scroll-Wheel-in-Access-forms#S5

 Which is where he first used the technique of loading a COM object into memory.  It gives a little more detail and insight as to what is actually happening.

JimD.
0
 
DatabaseMX (Joe Anderson - Microsoft MVP, Access and Data Platform)Commented:
"Im I missing something?"
Yes.  What you are missing is ... it's proprietary.  

My suggestion:  Use the app to build a truly global error handler.  I'm incorporating it into my apps, as I indicated in the testimonial.  I've waited for years for a real global error handler.

mx
0
 
MilewskpAuthor Commented:
Thanks everyone for your input; I'll split the points.
0
 
MilewskpAuthor Commented:
Thanks everyone.
0
 
DatabaseMX (Joe Anderson - Microsoft MVP, Access and Data Platform)Commented:
)
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 5
  • 5
  • 5
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now