• Welcome to Valhalla Legends Archive.
 

VB error handling

Started by Adron, November 30, 2003, 06:20 AM

Previous topic - Next topic

Adron

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

Quote from: CupHead on November 26, 2003, 01:00 PM
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:

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.


Grok

#1
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.

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...


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


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.

Banana fanna fo fanna

Quote from: TheMinistered on November 30, 2003, 11:52 AM
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...


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


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.

Ew? :)

Adron

Quote from: Grok on November 30, 2003, 11:26 AM
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.

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.

Adron

Quote from: TheMinistered on November 30, 2003, 11:52 AM
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...


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


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.

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.

Banana fanna fo fanna

I've found an extremely good strategy is to have VB communicate with a backend app, either through DLLs or XML-RPC.

Skywing

Quote from: St0rm.iD on December 01, 2003, 03:08 PM
I've found an extremely good strategy is to have VB communicate with a backend app, either through DLLs or XML-RPC.
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.

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.

What do you mean?  The code can be handled by a generic exception handler like so:

// push generic exception handler jump table address on the stack and setup the SEH
004019F6 6896104000 push 00401096


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

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.

Adron

Quote from: St0rm.iD on December 01, 2003, 03:08 PM
I've found an extremely good strategy is to have VB communicate with a backend app, either through DLLs or XML-RPC.

How does this help? Don't you still have to write error handling code in each and every event called by VB/Windows?

Banana fanna fo fanna

Yeah, but you have less subs to write error handlers for.

Grok


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:


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


... the error handling code from Function1 is raised   Anyway, not entirely relevant, but I just thought I'd mention it.

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.
To restrict ones ability to learn based on current surroundings means to never learn anything at all. - DarkVirus