Re-entrancy of VB Error Handling

Re-entrancy of VB Error Handling

Post by Tony Proct » Fri, 08 Aug 2003 18:42:31

One for the archives here: another problem with the VB 'Err' object is that
it's a global object specific to each EXE and DLL, just like the 'App'
object is. Hence, it is not possible to have any error handling support code
in a DLL that implicitly manipulates your local 'Err' object. For instance,
an interface that automatically reports the system error message
corresponding to a non-zero Err.LastDLLError, or an interface that saves
your 'Err' object to avoid the re-entrancy problems discussed in this
thread. The 'Err' object would have to be an explicit parameter in such

Tony Parameter


Re-entrancy of VB Error Handling

Post by Larry Serf » Fri, 08 Aug 2003 22:15:21

Tony Proctor" < XXXX@XXXXX.COM > wrote

Not entirely. You can create a dll that will save your current state and
store that on a stack for recall later. If you create a dll that stores a
reference to your application's ErrObject on initialization, then you don't
need to pass it in every time.

For example, your ActiveX.DLL has 2 classes; the ErrorItem that stores
the error data and a Heap that stores a collection of ErrorItems:

'[ErrorItem] PublicNotCreatable
Option Explicit
Public Number As Long
Public Description As String
Public Source As String

'[Heap] MultiUse
Option Explicit

Private mError As ErrObject
Private mErrors As Collection
Private mHeapMax As Long

Public Property Let AppErrorObject(ByRef ErrorObject As ErrObject)
Set mError = ErrorObject
End Property

Public Property Let MaxCount(ByVal Count As Long)
mHeapMax = Count
End Property

Public Property Get LastError() As ErrorItem
Set LastError = mErrors(mErrors.Count)
End Property

Public Sub NewError()
Dim e As ErrorItem
Set e = New ErrorItem
With mError
e.Description = .Description
e.Number = .Number
e.Source = .Source
End With
mErrors.Add e
If mErrors.Count > mHeapMax Then mErrors.Remove 1
End Sub

Private Sub Class_Initialize()
mHeapMax = 100
Set mErrors = New Collection
End Sub

Private Sub Class_Terminate()
Set mErrors = Nothing
End Sub

With that referenced in a new project, you only need to call NewError
to have it save the current error:

Option Explicit
Private AppErr As ErrorStack.Heap

Private Sub Form_Load()
Set AppErr = New ErrorStack.Heap
AppErr.AppErrorObject = Err
End Sub

Private Sub Command1_Click()
On Error GoTo check

On Error GoTo -1
On Error GoTo NewError
' Your clean up code goes here
Me.BackColor = "A" ' Oops, another error
MsgBox "Won't get here"

Debug.Print "Current error = "; Err.Description
Debug.Print "Original error = "; AppErr.LastError.Description
End Sub

You can see then, that at the end of the procedure, the current error
as well as the original error is easily available. For that situation, the
output would be:

Current error = Type mismatch
Original error = Return without GoSub

Of course you could add more properties to that Heap to walk the
stack back if you need to, or save to a log file, or whatever. That
was just a bare bones example. But you can see that can put all your
error processing into the DLL, and let it record the errors as you
run into them and you don't need to pass in the ErrObject every time.

BTW: Where did this thread come from, I see no other posts to it?



Re-entrancy of VB Error Handling

Post by Ben Taylo » Sat, 09 Aug 2003 07:57:54

You do realise you've typed yourself called Tony Parameter?
was that an intentional joke?
Because if not, then it was all the more funny.