Valhalla Legends Forums Archive | Visual Basic Programming | VB error handling

AuthorMessageTime
Adron
I'm copying this post here, to see if I can get any responses from some of the skilled VB programmers here...

[quote author=CupHead link=board=5;threadid=3609;start=0#msg31698 date=1069873232]
4) Exception Handling

VB has excellent error handling in my opinion. You can not only create your own errors, but you can raise them whenever you like, be notified of what error it is, what line caused it, and even return control to the program after your code has adjusted. We all know about On Error Resume Next, which is essentially a catch-all that keeps your programs from crashing. Well, you can actually do:
[/quote]

I don't like VB's error handling at all for one big reason: Generic error handling is as far as I know impossible to implement without copy-pasting code.

That is: If I want to handle every error that can possibly happen and do some kind of clean shutdown, I would have to write an On Error statement, a label and handler (or call to a generic handler) into nearly every event handler of every object. (i.e. command1_mousedown, command1_click, command1_mousemove, command1_ ... etc)

I have been able to find no way to create a generic exception handler that is global to the application.

What's worse, VB doesn't even let any errors happening in such functions pass on to a possibly attached debugger, or to the operating system. You get a stupid "Run-time error X: Bla bla bla" box with an OK button instead of invoking Dr.Watson to create a dump file that could be debugged.

November 30, 2003, 12:20 PM
Grok
The only way I know to do what you ask is to construct your application in specific ways. However, writing by using control-structure stacking and nesting at the procedure level is sufficient only for your own code. Objects whose code is written by VB, such as the GUI windows and controls, do not raise their events to your handler. I don't know a way to do that.
November 30, 2003, 5:26 PM
TheMinistered
This might be going a bit far, but you could do some patching perhaps? I know that, in every function, it pushes the address of vbaExceptionHandler on the stack for error handling I believe...

[code]
* Reference To: MSVBVM60.__vbaExceptHandler, Ord:0000
:00401096 FF253C104000 Jmp dword ptr [0040103Ch]
[/code]

Perhaps try patching the jump table to a function in a module? I'm not sure... it's just a long shot at an answer.
November 30, 2003, 5:52 PM
St0rm.iD
[quote author=TheMinistered link=board=31;threadid=3963;start=0#msg32654 date=1070214752]
This might be going a bit far, but you could do some patching perhaps? I know that, in every function, it pushes the address of vbaExceptionHandler on the stack for error handling I believe...

[code]
* Reference To: MSVBVM60.__vbaExceptHandler, Ord:0000
:00401096 FF253C104000 Jmp dword ptr [0040103Ch]
[/code]

Perhaps try patching the jump table to a function in a module? I'm not sure... it's just a long shot at an answer.
[/quote]

Ew? :)
November 30, 2003, 6:00 PM
Adron
[quote author=Grok link=board=31;threadid=3963;start=0#msg32647 date=1070213209]
The only way I know to do what you ask is to construct your application in specific ways. However, writing by using control-structure stacking and nesting at the procedure level is sufficient only for your own code. Objects whose code is written by VB, such as the GUI windows and controls, do not raise their events to your handler. I don't know a way to do that.
[/quote]

Well, and VB being the language it is, it's very well suited for applications that have a lot of GUI interaction and not so much processing. A very large part of the code ends up GUI code, making most Visual Basic applications I write have a very large number of events called by VB/Windows.

It's rather unfortunate. Like you said, if most of the calls originated in a "main" or "WinMain" function like in C++, I could just add a global error handling there, but as it is now, there has to be handlers spread out all over the place.
December 1, 2003, 5:46 PM
Adron
[quote author=TheMinistered link=board=31;threadid=3963;start=0#msg32654 date=1070214752]
This might be going a bit far, but you could do some patching perhaps? I know that, in every function, it pushes the address of vbaExceptionHandler on the stack for error handling I believe...

[code]
* Reference To: MSVBVM60.__vbaExceptHandler, Ord:0000
:00401096 FF253C104000 Jmp dword ptr [0040103Ch]
[/code]

Perhaps try patching the jump table to a function in a module? I'm not sure... it's just a long shot at an answer.
[/quote]

I've been working along that path a long time ago. What I ended up having trouble with was determining whether a particular error was handled by the local code or would result in a VB run-time error message box popping up.

I still want to be able to write specific error handling for errors that I foresee and know what to do about; it's just the unknown ones (presumably bugs) that I want a catch-all for to provide me with good information, like a stack-trace.

It seems rather complex though, perhaps requiring a DLL written in C++ to get the calling conventions and register preserving right.
December 1, 2003, 5:47 PM
St0rm.iD
I've found an extremely good strategy is to have VB communicate with a backend app, either through DLLs or XML-RPC.
December 1, 2003, 9:08 PM
Skywing
[quote author=St0rm.iD link=board=31;threadid=3963;start=0#msg32953 date=1070312882]
I've found an extremely good strategy is to have VB communicate with a backend app, either through DLLs or XML-RPC.
[/quote]
This isn't an option for an already-written app, and this probably won't be an option for an app with strict design requirements.
December 1, 2003, 9:17 PM
TheMinistered
[quote]
... determining whether a particular error was handled by the local code or would result in a VB run-time error message box popping up.
[/quote]

What do you mean? The code can be handled by a generic exception handler like so:
[code]
// push generic exception handler jump table address on the stack and setup the SEH
004019F6 6896104000 push 00401096
[/code]

The code for local error handling is a little more complex, but it still uses a generic exception handler. I would poke around a few of the following procs: vbaOnError, vbaExitProc (this appears to be used in some local error handling), vbaErrorOverflow, vbaFPException
December 2, 2003, 9:24 PM
Adron
What I mean is that I want to be able to use local error handling inside functions.

Stupid example:

On Error Resume Next
CommitTrans
If Err = 0 Then MsgBox "Error: Missing CommitTrans detected!"
On Error Goto 0/somehandler/whatever to restore behaviour


The global error handling shouldn't interfere with that. And it shouldn't require writing code in every event handler called from VB/Windows. I don't want to replace the coded VB error handling, only the implicit VB error handling of errors that don't have a specific handler written for them.
December 2, 2003, 11:29 PM
Adron
[quote author=St0rm.iD link=board=31;threadid=3963;start=0#msg32953 date=1070312882]
I've found an extremely good strategy is to have VB communicate with a backend app, either through DLLs or XML-RPC.
[/quote]

How does this help? Don't you still have to write error handling code in each and every event called by VB/Windows?
December 2, 2003, 11:30 PM
St0rm.iD
Yeah, but you have less subs to write error handlers for.
December 3, 2003, 7:56 PM
Grok
YAY @ Adron @ vbdump
December 11, 2003, 4:01 PM
CupHead
Just sort of an afterthought. VB's error handing can sometimes be useful and other times be painful. I don't know how VB compilations work entirely (i.e. if they inline all functions), but you have to bear in mind that errors cascade from the caller so if you do something like this:

[code]
Private Sub Function1()
On Error GoTo ErrorHandler

Call Function2()

Exit Sub

ErrorHandler:
Select Case Err.Number
Case Else
Debug.Print "Error: (" & Err.Number & ") " & Err.Description
End Select
End Sub

Private Sub Function2()
Dim strWhatever As String
strWhatever = "Test"
strWhatever = Mid(strWhatever, 0, 1)
End Sub
[/code]

... the error handling code from Function1 is raised Anyway, not entirely relevant, but I just thought I'd mention it.
December 11, 2003, 6:23 PM
DarkVirus
Adron, perhaps switch to VB.Net and try out their Try...Catch error system? It's really nice for catching those forseeable or unforseeable bugs while using about 1/2 the code as you would on On Error systems used in VB 6.0.
December 11, 2003, 10:12 PM
Adron
try/catch exists in C++ too, but I'm not switching languages. I have however written a little DLL which will capture unhandled VB errors and write a minidump. If anyone's interested, post, and I might publish.
December 12, 2003, 12:35 AM
Grok
[quote author=Adron link=board=31;threadid=3963;start=15#msg34857 date=1071189341]
try/catch exists in C++ too, but I'm not switching languages. I have however written a little DLL which will capture unhandled VB errors and write a minidump. If anyone's interested, post, and I might publish.
[/quote]

Hey I wrote one too, but mine is copyrighted. Patent pending. My lawyer is sending a C&D letter in the morning. :P
December 12, 2003, 1:22 AM
Skywing
[quote author=DarkVirus link=board=31;threadid=3963;start=0#msg34826 date=1071180768]
Adron, perhaps switch to VB.Net and try out their Try...Catch error system? It's really nice for catching those forseeable or unforseeable bugs while using about 1/2 the code as you would on On Error systems used in VB 6.0.
[/quote]
You can't just switch a production system like that, especially one worked on by a team of programmers. Customers won't like the added dependencies suddenly appearing without warning, either.
December 12, 2003, 7:27 AM
DarkVirus
[quote author=Skywing link=board=31;threadid=3963;start=15#msg34897 date=1071214077]
[quote author=DarkVirus link=board=31;threadid=3963;start=0#msg34826 date=1071180768]
Adron, perhaps switch to VB.Net and try out their Try...Catch error system? It's really nice for catching those forseeable or unforseeable bugs while using about 1/2 the code as you would on On Error systems used in VB 6.0.
[/quote]
You can't just switch a production system like that, especially one worked on by a team of programmers. Customers won't like the added dependencies suddenly appearing without warning, either.
[/quote]

I also wasn't aware of the context of what the program was even about or who was creating it. I thought it was a general topic about error handling. I also wasn't aware that Try...Catch was available in C++.
December 12, 2003, 1:14 PM
Adron
Well, the question was asked with a particular project in mind, which happens to be coded in VB (non-.NET). I would've preferred if it was coded in C++, which has better error handling in addition to everything else, but that would take too much time. So, I'm stuck with making the best of it!

At least it's not so difficult to write parts (like VBDump.dll) in C++ and call them from the VB parts.
December 12, 2003, 7:44 PM
Adron
Now, the wonderful vbdump Attach function returns a BOOL.

True - vbdump is attached
False - vbdump failed to attach

or

-1 - vbdump was already attached!
December 12, 2003, 9:40 PM
Skywing
[quote author=Adron link=board=31;threadid=3963;start=15#msg34993 date=1071265209]
Now, the wonderful vbdump Attach function returns a BOOL.

True - vbdump is attached
False - vbdump failed to attach

or

-1 - vbdump was already attached!
[/quote]
Ah, so it's another functions that actually returns a Troolean, like GetMessage. Just what the world needs...
December 12, 2003, 11:34 PM
Adron
Yup!

But, it actually returns a "true", non-zero, value whenever it ends up being attached after call. Whether it was already attached or it attached during this call.
December 13, 2003, 11:04 AM
Skywing
[quote author=Adron link=board=31;threadid=3963;start=15#msg35085 date=1071313496]
Yup!

But, it actually returns a "true", non-zero, value whenever it ends up being attached after call. Whether it was already attached or it attached during this call.
[/quote]
I propose that we create a new type, TROOL, for this purpose.
#define TRUE 1
#define FALSE 0
#define MAYBE -1
December 13, 2003, 6:16 PM
CupHead
That's such a 2-bit data type. *cough*
December 13, 2003, 7:46 PM
Adron
I'm currently working on the next version with non-fixed patch offsets for the messagebox in msvbvm*

Will be doing a search through the address space if I can't find a match at the known possible locations.
December 13, 2003, 7:51 PM

Search