Discussion:
Err object being reset and returning err.number = 0
(too old to reply)
TC
2005-01-20 03:26:36 UTC
Permalink
Hello,

I am experiencing an odd and intermittent problem with a COM addin that I've built. I have seen this problem once before in a Word global template.

Imagine code structured like the following pseudo-code:

Sub Something
On Error Goto ErrorHandler

' routine goes here

ErrorHandler:

If err.number <> 0 then
ErrorMessage err
end if
End Sub

Sub ErrorMessage(byval objErr as ErrObject)
msgbox "Error: " & objErr.Number & vbcr & "Description: " & objErr.Description
End Sub

If the above routine causes an error, the message box returned reveals "Error: 0", i.e. no error, but this is not possible because otherwise, the ErrorMessage routine would not be called.

I resolved this once before by passing in the err.number & err.description values as opposed to the err object itself. It was as if the OS was losing its thread to the err object.

Has anyone else experienced this?

Regards,

TC
Jezebel
2005-01-20 03:39:11 UTC
Permalink
An error-handling routine should end with some form of resume statement,
otherwise your subsequent code is still within the error-handling context,
which screws up the handling of any further error. A better construction is
along these lines (remove the bits you don't need) --

Sub Something()

Const pFunctionName = "Something"
Dim pErrorResponse as long

On Error Goto Something_Error

' routine goes here

Something_Exit:
On error resume next
... function clean-up if any
Err.clear
Exit Sub

Something_Error:
Select case err.number
Case vbObjectError
' special handling, if any
Case Else
pErrorResponse = Msgbox(err.description, vbIgnoreRetryCancel,
pFunctionName)
End Select

If pErrorResponse = vbRetry then Resume
If pErrorResponse = vbIgnore then Resume Next
Resume Something_Exit

End Sub




"TC" <***@yahoo.com> wrote in message news:ujpHb$p$***@TK2MSFTNGP12.phx.gbl...
Hello,

I am experiencing an odd and intermittent problem with a COM addin that I've
built. I have seen this problem once before in a Word global template.

Imagine code structured like the following pseudo-code:

Sub Something
On Error Goto ErrorHandler

' routine goes here

ErrorHandler:

If err.number <> 0 then
ErrorMessage err
end if
End Sub

Sub ErrorMessage(byval objErr as ErrObject)
msgbox "Error: " & objErr.Number & vbcr & "Description: " &
objErr.Description
End Sub

If the above routine causes an error, the message box returned reveals
"Error: 0", i.e. no error, but this is not possible because otherwise, the
ErrorMessage routine would not be called.

I resolved this once before by passing in the err.number & err.description
values as opposed to the err object itself. It was as if the OS was losing
its thread to the err object.

Has anyone else experienced this?

Regards,

TC
TC
2005-01-20 04:10:40 UTC
Permalink
Hey Jezebel,

I don't think that you under stood my question.

For what it's worth, your error handler does not need to be that complicated nor do you need to repeat all of that code in all of your routines.

See concrete example below:

' This routine removes all references, etc. and ends the current user session
Public Sub QuitSession()

Const constrROUTINE_NAME As String = "QuitSession"

On Error GoTo ErrorHandler

' If all objects have been destroyed, exit the routine
If g_objThisAddIn Is Nothing Then
GoTo ErrorHandler
End If

If Not g_objThisAddIn.Soap Is Nothing Then
With g_objThisAddIn.Soap
If .IsConnected = True Then
.SoapMethod = EndSession
.SoapMethodName = g_constrEND_SESSION
'disconnect the session!
.CallSoapMethod
.CompleteSoapCall
End If
End With
End If

' Save settings
SaveToolbarSettings

' Destroy addin instance
Set g_objThisAddIn = Nothing

ErrorHandler:

Select Case Err.Number

Case 0 ' Do Nothing

' Unexpected error has occurred
Case Else
Call AppMessageBoxes(g_constrMODULE_AND_METHOD & m_constrMODULE_NAME & g_constrDOUBLE_SPACE & constrROUTINE_NAME, _
vbExclamation + vbOKOnly + vbMsgBoxSetForeground, g_constrERROR, , , Err)

End Select

End Sub
Below is a generic errorhandler and messagebox handler for an entire application:
Public Sub AppMessageBoxes(ByVal strPrompt As String, _
ByVal lngButtons As Long, _
ByVal strTitle As String, _
Optional ByVal strHelpfile As String, _
Optional ByVal lngContext As Long, _
Optional ByVal objErr As Object, _
Optional ByRef intVal As Integer)

Const constrROUTINE_NAME As String = "AppMessageBoxes"

' There is no error trapping in this routine because
' error trapping will clear the error object that
' is passed to this error handling routine upon entrance
' On Error GoTo ErrorHandler

If Not objErr Is Nothing Then
Call MsgBox(g_constrERROR & objErr.Number & vbCr & objErr.Description & vbCr & vbCr & strPrompt, _
lngButtons, strTitle)

' Log the error
If g_objThisAddIn.CurrentUser.PrintErrorLog = True Then
LogError strPrompt, objErr.Number, objErr.Description
End If
ElseIf intVal = 0 Then
intVal = MsgBox(strPrompt, lngButtons, strTitle)
Else
Call MsgBox(strPrompt, lngButtons, strTitle)
End If

ErrorHandler:

Select Case Err.Number

Case 0 ' Do Nothing

' Unexpected error has occurred
Case Else

End Select

' Clear any unhandled errors
If Err.Number <> 0 Then
Err.Clear
End If

End Sub
Lastly, my actual question was not answered which was:

Has anyone seen or does anyone know the cause of an err object's Number property being reset when it is passed into a handling routine?

Technically, this should not happen because the object has not been released from memory within the original calling routine.

Thanks & Regards,

Todd
Post by Jezebel
An error-handling routine should end with some form of resume statement,
otherwise your subsequent code is still within the error-handling context,
which screws up the handling of any further error. A better construction is
along these lines (remove the bits you don't need) --
Sub Something()
Const pFunctionName = "Something"
Dim pErrorResponse as long
On Error Goto Something_Error
' routine goes here
On error resume next
... function clean-up if any
Err.clear
Exit Sub
Select case err.number
Case vbObjectError
' special handling, if any
Case Else
pErrorResponse = Msgbox(err.description, vbIgnoreRetryCancel,
pFunctionName)
End Select
If pErrorResponse = vbRetry then Resume
If pErrorResponse = vbIgnore then Resume Next
Resume Something_Exit
End Sub
Hello,
I am experiencing an odd and intermittent problem with a COM addin that I've
built. I have seen this problem once before in a Word global template.
Sub Something
On Error Goto ErrorHandler
' routine goes here
If err.number <> 0 then
ErrorMessage err
end if
End Sub
Sub ErrorMessage(byval objErr as ErrObject)
msgbox "Error: " & objErr.Number & vbcr & "Description: " & objErr.Description
End Sub
If the above routine causes an error, the message box returned reveals
"Error: 0", i.e. no error, but this is not possible because otherwise, the
ErrorMessage routine would not be called.
I resolved this once before by passing in the err.number & err.description
values as opposed to the err object itself. It was as if the OS was losing
its thread to the err object.
Has anyone else experienced this?
Regards,
TC
Jezebel
2005-01-20 04:38:58 UTC
Permalink
TC, the big difference is that my coide works and yours doesn't. I don't
mind if you don't want the answer, but to defend non-functioning code seems
a little obtuse.


"TC" <***@yahoo.com> wrote in message news:e5JxEYq$***@TK2MSFTNGP10.phx.gbl...
Hey Jezebel,

I don't think that you under stood my question.

For what it's worth, your error handler does not need to be that complicated
nor do you need to repeat all of that code in all of your routines.

See concrete example below:

' This routine removes all references, etc. and ends the current user
session
Public Sub QuitSession()

Const constrROUTINE_NAME As String = "QuitSession"

On Error GoTo ErrorHandler

' If all objects have been destroyed, exit the routine
If g_objThisAddIn Is Nothing Then
GoTo ErrorHandler
End If

If Not g_objThisAddIn.Soap Is Nothing Then
With g_objThisAddIn.Soap
If .IsConnected = True Then
.SoapMethod = EndSession
.SoapMethodName = g_constrEND_SESSION
'disconnect the session!
.CallSoapMethod
.CompleteSoapCall
End If
End With
End If

' Save settings
SaveToolbarSettings

' Destroy addin instance
Set g_objThisAddIn = Nothing

ErrorHandler:

Select Case Err.Number

Case 0 ' Do Nothing

' Unexpected error has occurred
Case Else
Call AppMessageBoxes(g_constrMODULE_AND_METHOD &
m_constrMODULE_NAME & g_constrDOUBLE_SPACE & constrROUTINE_NAME, _
vbExclamation + vbOKOnly +
vbMsgBoxSetForeground, g_constrERROR, , , Err)

End Select

End Sub
Below is a generic errorhandler and messagebox handler for an entire
application:
Public Sub AppMessageBoxes(ByVal strPrompt As String, _
ByVal lngButtons As Long, _
ByVal strTitle As String, _
Optional ByVal strHelpfile As String, _
Optional ByVal lngContext As Long, _
Optional ByVal objErr As Object, _
Optional ByRef intVal As Integer)

Const constrROUTINE_NAME As String = "AppMessageBoxes"

' There is no error trapping in this routine because
' error trapping will clear the error object that
' is passed to this error handling routine upon entrance
' On Error GoTo ErrorHandler

If Not objErr Is Nothing Then
Call MsgBox(g_constrERROR & objErr.Number & vbCr &
objErr.Description & vbCr & vbCr & strPrompt, _
lngButtons, strTitle)

' Log the error
If g_objThisAddIn.CurrentUser.PrintErrorLog = True Then
LogError strPrompt, objErr.Number, objErr.Description
End If
ElseIf intVal = 0 Then
intVal = MsgBox(strPrompt, lngButtons, strTitle)
Else
Call MsgBox(strPrompt, lngButtons, strTitle)
End If

ErrorHandler:

Select Case Err.Number

Case 0 ' Do Nothing

' Unexpected error has occurred
Case Else

End Select

' Clear any unhandled errors
If Err.Number <> 0 Then
Err.Clear
End If

End Sub
Lastly, my actual question was not answered which was:

Has anyone seen or does anyone know the cause of an err object's Number
property being reset when it is passed into a handling routine?

Technically, this should not happen because the object has not been released
from memory within the original calling routine.

Thanks & Regards,

Todd
Post by Jezebel
An error-handling routine should end with some form of resume statement,
otherwise your subsequent code is still within the error-handling context,
which screws up the handling of any further error. A better construction is
along these lines (remove the bits you don't need) --
Sub Something()
Const pFunctionName = "Something"
Dim pErrorResponse as long
On Error Goto Something_Error
' routine goes here
On error resume next
... function clean-up if any
Err.clear
Exit Sub
Select case err.number
Case vbObjectError
' special handling, if any
Case Else
pErrorResponse = Msgbox(err.description, vbIgnoreRetryCancel,
pFunctionName)
End Select
If pErrorResponse = vbRetry then Resume
If pErrorResponse = vbIgnore then Resume Next
Resume Something_Exit
End Sub
Hello,
I am experiencing an odd and intermittent problem with a COM addin that I've
built. I have seen this problem once before in a Word global template.
Sub Something
On Error Goto ErrorHandler
' routine goes here
If err.number <> 0 then
ErrorMessage err
end if
End Sub
Sub ErrorMessage(byval objErr as ErrObject)
msgbox "Error: " & objErr.Number & vbcr & "Description: " & objErr.Description
End Sub
If the above routine causes an error, the message box returned reveals
"Error: 0", i.e. no error, but this is not possible because otherwise, the
ErrorMessage routine would not be called.
I resolved this once before by passing in the err.number & err.description
values as opposed to the err object itself. It was as if the OS was losing
its thread to the err object.
Has anyone else experienced this?
Regards,
TC
TC
2005-01-20 07:05:43 UTC
Permalink
Hey Jezebel,

Actually, it does work with exception of a couple of machines.

Secondly, I wasn't interested in getting into a p _ _ _ sing match over code
constructs.

Lastly, you'll have significant repeated code is what I'm offering to you.
You should also note that you don't have any type of logging in your code
either (i.e. when it is implemented you can add that in about a 1000+ places
as well).

Hope that's less obtuse.

You still answer the original question.

Regards,

TC
Post by Jezebel
TC, the big difference is that my coide works and yours doesn't. I don't
mind if you don't want the answer, but to defend non-functioning code seems
a little obtuse.
Hey Jezebel,
I don't think that you under stood my question.
For what it's worth, your error handler does not need to be that complicated
nor do you need to repeat all of that code in all of your routines.
' This routine removes all references, etc. and ends the current user session
Public Sub QuitSession()
Const constrROUTINE_NAME As String = "QuitSession"
On Error GoTo ErrorHandler
' If all objects have been destroyed, exit the routine
If g_objThisAddIn Is Nothing Then
GoTo ErrorHandler
End If
If Not g_objThisAddIn.Soap Is Nothing Then
With g_objThisAddIn.Soap
If .IsConnected = True Then
.SoapMethod = EndSession
.SoapMethodName = g_constrEND_SESSION
'disconnect the session!
.CallSoapMethod
.CompleteSoapCall
End If
End With
End If
' Save settings
SaveToolbarSettings
' Destroy addin instance
Set g_objThisAddIn = Nothing
Select Case Err.Number
Case 0 ' Do Nothing
' Unexpected error has occurred
Case Else
Call AppMessageBoxes(g_constrMODULE_AND_METHOD &
m_constrMODULE_NAME & g_constrDOUBLE_SPACE & constrROUTINE_NAME, _
vbExclamation + vbOKOnly +
vbMsgBoxSetForeground, g_constrERROR, , , Err)
End Select
End Sub
Public Sub AppMessageBoxes(ByVal strPrompt As String, _
ByVal lngButtons As Long, _
ByVal strTitle As String, _
Optional ByVal strHelpfile As String, _
Optional ByVal lngContext As Long, _
Optional ByVal objErr As Object, _
Optional ByRef intVal As Integer)
Const constrROUTINE_NAME As String = "AppMessageBoxes"
' There is no error trapping in this routine because
' error trapping will clear the error object that
' is passed to this error handling routine upon entrance
' On Error GoTo ErrorHandler
If Not objErr Is Nothing Then
Call MsgBox(g_constrERROR & objErr.Number & vbCr &
objErr.Description & vbCr & vbCr & strPrompt, _
lngButtons, strTitle)
' Log the error
If g_objThisAddIn.CurrentUser.PrintErrorLog = True Then
LogError strPrompt, objErr.Number, objErr.Description
End If
ElseIf intVal = 0 Then
intVal = MsgBox(strPrompt, lngButtons, strTitle)
Else
Call MsgBox(strPrompt, lngButtons, strTitle)
End If
Select Case Err.Number
Case 0 ' Do Nothing
' Unexpected error has occurred
Case Else
End Select
' Clear any unhandled errors
If Err.Number <> 0 Then
Err.Clear
End If
End Sub
Has anyone seen or does anyone know the cause of an err object's Number
property being reset when it is passed into a handling routine?
Technically, this should not happen because the object has not been released
from memory within the original calling routine.
Thanks & Regards,
Todd
Post by Jezebel
An error-handling routine should end with some form of resume statement,
otherwise your subsequent code is still within the error-handling context,
which screws up the handling of any further error. A better construction
is
Post by Jezebel
along these lines (remove the bits you don't need) --
Sub Something()
Const pFunctionName = "Something"
Dim pErrorResponse as long
On Error Goto Something_Error
' routine goes here
On error resume next
... function clean-up if any
Err.clear
Exit Sub
Select case err.number
Case vbObjectError
' special handling, if any
Case Else
pErrorResponse = Msgbox(err.description, vbIgnoreRetryCancel,
pFunctionName)
End Select
If pErrorResponse = vbRetry then Resume
If pErrorResponse = vbIgnore then Resume Next
Resume Something_Exit
End Sub
Hello,
I am experiencing an odd and intermittent problem with a COM addin that
I've
Post by Jezebel
built. I have seen this problem once before in a Word global template.
Sub Something
On Error Goto ErrorHandler
' routine goes here
If err.number <> 0 then
ErrorMessage err
end if
End Sub
Sub ErrorMessage(byval objErr as ErrObject)
msgbox "Error: " & objErr.Number & vbcr & "Description: " & objErr.Description
End Sub
If the above routine causes an error, the message box returned reveals
"Error: 0", i.e. no error, but this is not possible because otherwise,
the
Post by Jezebel
ErrorMessage routine would not be called.
I resolved this once before by passing in the err.number &
err.description
values as opposed to the err object itself. It was as if the OS was
losing
Post by Jezebel
its thread to the err object.
Has anyone else experienced this?
Regards,
TC
Jezebel
2005-01-20 10:17:26 UTC
Permalink
Post by TC
Actually, it does work with exception of a couple of machines.
To anyone but an IT person, that counts as "not working".
TC
2005-01-20 19:14:10 UTC
Permalink
Nonetheless, you didn't answer my question.

The only question I had was:

"What causes the behavior."

I know how to address the issue.

Secondly, the code was used successfully in a commercial, not corporate,
software solution but the error object was passed out to a consumer.

Do you have an answer to my actual question?
Post by Jezebel
Post by TC
Actually, it does work with exception of a couple of machines.
To anyone but an IT person, that counts as "not working".
Joseph Geretz
2005-01-20 05:16:36 UTC
Permalink
Hi TC,

I've done quite a bit of work with VB error handling. I've seen the symptom
you describe when an error handler calls a method which has it's own error
trap (On Error statement) . For this reason we do very little inside our own
error handlers aside from calling a few of our own methods which are
specifically designed for use inside an error handler. (Similar in concept
to what you are doing. I see nothing wrong with this approach per se.)

That being said, I see the commented On Error trap in your error handler
method, along with the error handler in that method which is ostensibly
never being called. I'm confused. Why comment out the error trap, and retain
a 'dead' error handler? Are you sure that the source code is absolutely
faithful to the binary in which you are seeing these symptoms?

Second, you seem to be missing an Exit Sub before your error handlers. I see
what you are trying to do by trapping for Err.Number = 0 in your error
handlers however typical code construction would prevent entry into the
handler to begin with unless an error has occurred. an Exit Sub just before
your handler will go a long way toward code clarity in this respect.

Another interesting thing you are doing is passing the Err object as a
parameter. I wonder what effect that is having. In our error handling
methods we pass the Err properties we are interested in as separate
parameters (e.g. Err.Number, Err.Description, etc.).

Hope this helps,

- Joe Geretz -

"TC" <***@yahoo.com> wrote in message news:e5JxEYq$***@TK2MSFTNGP10.phx.gbl...
Hey Jezebel,

I don't think that you under stood my question.

For what it's worth, your error handler does not need to be that complicated
nor do you need to repeat all of that code in all of your routines.

See concrete example below:

' This routine removes all references, etc. and ends the current user
session
Public Sub QuitSession()

Const constrROUTINE_NAME As String = "QuitSession"

On Error GoTo ErrorHandler

' If all objects have been destroyed, exit the routine
If g_objThisAddIn Is Nothing Then
GoTo ErrorHandler
End If

If Not g_objThisAddIn.Soap Is Nothing Then
With g_objThisAddIn.Soap
If .IsConnected = True Then
.SoapMethod = EndSession
.SoapMethodName = g_constrEND_SESSION
'disconnect the session!
.CallSoapMethod
.CompleteSoapCall
End If
End With
End If

' Save settings
SaveToolbarSettings

' Destroy addin instance
Set g_objThisAddIn = Nothing

ErrorHandler:

Select Case Err.Number

Case 0 ' Do Nothing

' Unexpected error has occurred
Case Else
Call AppMessageBoxes(g_constrMODULE_AND_METHOD &
m_constrMODULE_NAME & g_constrDOUBLE_SPACE & constrROUTINE_NAME, _
vbExclamation + vbOKOnly +
vbMsgBoxSetForeground, g_constrERROR, , , Err)

End Select

End Sub
Below is a generic errorhandler and messagebox handler for an entire
application:
Public Sub AppMessageBoxes(ByVal strPrompt As String, _
ByVal lngButtons As Long, _
ByVal strTitle As String, _
Optional ByVal strHelpfile As String, _
Optional ByVal lngContext As Long, _
Optional ByVal objErr As Object, _
Optional ByRef intVal As Integer)

Const constrROUTINE_NAME As String = "AppMessageBoxes"

' There is no error trapping in this routine because
' error trapping will clear the error object that
' is passed to this error handling routine upon entrance
' On Error GoTo ErrorHandler

If Not objErr Is Nothing Then
Call MsgBox(g_constrERROR & objErr.Number & vbCr &
objErr.Description & vbCr & vbCr & strPrompt, _
lngButtons, strTitle)

' Log the error
If g_objThisAddIn.CurrentUser.PrintErrorLog = True Then
LogError strPrompt, objErr.Number, objErr.Description
End If
ElseIf intVal = 0 Then
intVal = MsgBox(strPrompt, lngButtons, strTitle)
Else
Call MsgBox(strPrompt, lngButtons, strTitle)
End If

ErrorHandler:

Select Case Err.Number

Case 0 ' Do Nothing

' Unexpected error has occurred
Case Else

End Select

' Clear any unhandled errors
If Err.Number <> 0 Then
Err.Clear
End If

End Sub
Lastly, my actual question was not answered which was:

Has anyone seen or does anyone know the cause of an err object's Number
property being reset when it is passed into a handling routine?

Technically, this should not happen because the object has not been released
from memory within the original calling routine.

Thanks & Regards,

Todd
Post by Jezebel
An error-handling routine should end with some form of resume statement,
otherwise your subsequent code is still within the error-handling context,
which screws up the handling of any further error. A better construction is
along these lines (remove the bits you don't need) --
Sub Something()
Const pFunctionName = "Something"
Dim pErrorResponse as long
On Error Goto Something_Error
' routine goes here
On error resume next
... function clean-up if any
Err.clear
Exit Sub
Select case err.number
Case vbObjectError
' special handling, if any
Case Else
pErrorResponse = Msgbox(err.description, vbIgnoreRetryCancel,
pFunctionName)
End Select
If pErrorResponse = vbRetry then Resume
If pErrorResponse = vbIgnore then Resume Next
Resume Something_Exit
End Sub
Hello,
I am experiencing an odd and intermittent problem with a COM addin that I've
built. I have seen this problem once before in a Word global template.
Sub Something
On Error Goto ErrorHandler
' routine goes here
If err.number <> 0 then
ErrorMessage err
end if
End Sub
Sub ErrorMessage(byval objErr as ErrObject)
msgbox "Error: " & objErr.Number & vbcr & "Description: " & objErr.Description
End Sub
If the above routine causes an error, the message box returned reveals
"Error: 0", i.e. no error, but this is not possible because otherwise, the
ErrorMessage routine would not be called.
I resolved this once before by passing in the err.number & err.description
values as opposed to the err object itself. It was as if the OS was losing
its thread to the err object.
Has anyone else experienced this?
Regards,
TC
TC
2005-01-20 07:12:38 UTC
Permalink
Hey Joseph,

Yep. I've already changed the errorhandler so that it takes the parameters
rather than the object.

Question is, why does it intermittently fail on only a select few machines
and certain times by not maintaining its own reference to the error number?
Very strange.

As for leaving out the "Exit Sub" statement, that was a habit that I
acquired from a former colleague whilst working at one of investment banks
in NYC. Basically, the idea being: if there is no error, it's going to
exit anyway. It also forces and error check. For me, I've considered
adding it back over the years solely for performance purposes.

I left the commented out errorhandler in the error routine is actually a
typo. The routine originally used an On Error Resume Next.

In short, I know how to circumvent the issue, I was just wondering if
someone had an explanation.

Regards,

Todd
Post by Joseph Geretz
Hi TC,
I've done quite a bit of work with VB error handling. I've seen the
symptom you describe when an error handler calls a method which has it's
own error trap (On Error statement) . For this reason we do very little
inside our own error handlers aside from calling a few of our own methods
which are specifically designed for use inside an error handler. (Similar
in concept to what you are doing. I see nothing wrong with this approach
per se.)
That being said, I see the commented On Error trap in your error handler
method, along with the error handler in that method which is ostensibly
never being called. I'm confused. Why comment out the error trap, and
retain a 'dead' error handler? Are you sure that the source code is
absolutely faithful to the binary in which you are seeing these symptoms?
Second, you seem to be missing an Exit Sub before your error handlers. I
see what you are trying to do by trapping for Err.Number = 0 in your error
handlers however typical code construction would prevent entry into the
handler to begin with unless an error has occurred. an Exit Sub just
before your handler will go a long way toward code clarity in this
respect.
Another interesting thing you are doing is passing the Err object as a
parameter. I wonder what effect that is having. In our error handling
methods we pass the Err properties we are interested in as separate
parameters (e.g. Err.Number, Err.Description, etc.).
Hope this helps,
- Joe Geretz -
Hey Jezebel,
I don't think that you under stood my question.
For what it's worth, your error handler does not need to be that
complicated nor do you need to repeat all of that code in all of your
routines.
' This routine removes all references, etc. and ends the current user session
Public Sub QuitSession()
Const constrROUTINE_NAME As String = "QuitSession"
On Error GoTo ErrorHandler
' If all objects have been destroyed, exit the routine
If g_objThisAddIn Is Nothing Then
GoTo ErrorHandler
End If
If Not g_objThisAddIn.Soap Is Nothing Then
With g_objThisAddIn.Soap
If .IsConnected = True Then
.SoapMethod = EndSession
.SoapMethodName = g_constrEND_SESSION
'disconnect the session!
.CallSoapMethod
.CompleteSoapCall
End If
End With
End If
' Save settings
SaveToolbarSettings
' Destroy addin instance
Set g_objThisAddIn = Nothing
Select Case Err.Number
Case 0 ' Do Nothing
' Unexpected error has occurred
Case Else
Call AppMessageBoxes(g_constrMODULE_AND_METHOD &
m_constrMODULE_NAME & g_constrDOUBLE_SPACE & constrROUTINE_NAME, _
vbExclamation + vbOKOnly +
vbMsgBoxSetForeground, g_constrERROR, , , Err)
End Select
End Sub
Public Sub AppMessageBoxes(ByVal strPrompt As String, _
ByVal lngButtons As Long, _
ByVal strTitle As String, _
Optional ByVal strHelpfile As String, _
Optional ByVal lngContext As Long, _
Optional ByVal objErr As Object, _
Optional ByRef intVal As Integer)
Const constrROUTINE_NAME As String = "AppMessageBoxes"
' There is no error trapping in this routine because
' error trapping will clear the error object that
' is passed to this error handling routine upon entrance
' On Error GoTo ErrorHandler
If Not objErr Is Nothing Then
Call MsgBox(g_constrERROR & objErr.Number & vbCr &
objErr.Description & vbCr & vbCr & strPrompt, _
lngButtons, strTitle)
' Log the error
If g_objThisAddIn.CurrentUser.PrintErrorLog = True Then
LogError strPrompt, objErr.Number, objErr.Description
End If
ElseIf intVal = 0 Then
intVal = MsgBox(strPrompt, lngButtons, strTitle)
Else
Call MsgBox(strPrompt, lngButtons, strTitle)
End If
Select Case Err.Number
Case 0 ' Do Nothing
' Unexpected error has occurred
Case Else
End Select
' Clear any unhandled errors
If Err.Number <> 0 Then
Err.Clear
End If
End Sub
Has anyone seen or does anyone know the cause of an err object's Number
property being reset when it is passed into a handling routine?
Technically, this should not happen because the object has not been
released from memory within the original calling routine.
Thanks & Regards,
Todd
Post by Jezebel
An error-handling routine should end with some form of resume statement,
otherwise your subsequent code is still within the error-handling context,
which screws up the handling of any further error. A better construction is
along these lines (remove the bits you don't need) --
Sub Something()
Const pFunctionName = "Something"
Dim pErrorResponse as long
On Error Goto Something_Error
' routine goes here
On error resume next
... function clean-up if any
Err.clear
Exit Sub
Select case err.number
Case vbObjectError
' special handling, if any
Case Else
pErrorResponse = Msgbox(err.description, vbIgnoreRetryCancel,
pFunctionName)
End Select
If pErrorResponse = vbRetry then Resume
If pErrorResponse = vbIgnore then Resume Next
Resume Something_Exit
End Sub
Hello,
I am experiencing an odd and intermittent problem with a COM addin that I've
built. I have seen this problem once before in a Word global template.
Sub Something
On Error Goto ErrorHandler
' routine goes here
If err.number <> 0 then
ErrorMessage err
end if
End Sub
Sub ErrorMessage(byval objErr as ErrObject)
msgbox "Error: " & objErr.Number & vbcr & "Description: " & objErr.Description
End Sub
If the above routine causes an error, the message box returned reveals
"Error: 0", i.e. no error, but this is not possible because otherwise, the
ErrorMessage routine would not be called.
I resolved this once before by passing in the err.number &
err.description
values as opposed to the err object itself. It was as if the OS was losing
its thread to the err object.
Has anyone else experienced this?
Regards,
TC
TC
2005-01-20 19:26:26 UTC
Permalink
Hey Joseph,

A couple of final points.

I forgot to mention that the ErrorHandler in that message handler is not
actually dead at all. If a successful error object is passed into the
routine, it clears it. Also, if the "On Error Goto ErrorHandler" is
uncommented, it clears the object being passed in which defeats its purpose.

Also very interesting, I have been able to reproduce the behavior in a demo
app and if I put a breakpoint just prior to displaying the message and view
the objErr object in the Locals window, it displays the appropriate
information about the object. However, if I extract the err.number &
err.description and dump them in variables from within the same routine, it
works.

It only seems to lose its thread when the error message is actually called.

Very odd.

Regards,

Todd
Post by Joseph Geretz
Hi TC,
I've done quite a bit of work with VB error handling. I've seen the
symptom you describe when an error handler calls a method which has it's
own error trap (On Error statement) . For this reason we do very little
inside our own error handlers aside from calling a few of our own methods
which are specifically designed for use inside an error handler. (Similar
in concept to what you are doing. I see nothing wrong with this approach
per se.)
That being said, I see the commented On Error trap in your error handler
method, along with the error handler in that method which is ostensibly
never being called. I'm confused. Why comment out the error trap, and
retain a 'dead' error handler? Are you sure that the source code is
absolutely faithful to the binary in which you are seeing these symptoms?
Second, you seem to be missing an Exit Sub before your error handlers. I
see what you are trying to do by trapping for Err.Number = 0 in your error
handlers however typical code construction would prevent entry into the
handler to begin with unless an error has occurred. an Exit Sub just
before your handler will go a long way toward code clarity in this
respect.
Another interesting thing you are doing is passing the Err object as a
parameter. I wonder what effect that is having. In our error handling
methods we pass the Err properties we are interested in as separate
parameters (e.g. Err.Number, Err.Description, etc.).
Hope this helps,
- Joe Geretz -
Hey Jezebel,
I don't think that you under stood my question.
For what it's worth, your error handler does not need to be that
complicated nor do you need to repeat all of that code in all of your
routines.
' This routine removes all references, etc. and ends the current user session
Public Sub QuitSession()
Const constrROUTINE_NAME As String = "QuitSession"
On Error GoTo ErrorHandler
' If all objects have been destroyed, exit the routine
If g_objThisAddIn Is Nothing Then
GoTo ErrorHandler
End If
If Not g_objThisAddIn.Soap Is Nothing Then
With g_objThisAddIn.Soap
If .IsConnected = True Then
.SoapMethod = EndSession
.SoapMethodName = g_constrEND_SESSION
'disconnect the session!
.CallSoapMethod
.CompleteSoapCall
End If
End With
End If
' Save settings
SaveToolbarSettings
' Destroy addin instance
Set g_objThisAddIn = Nothing
Select Case Err.Number
Case 0 ' Do Nothing
' Unexpected error has occurred
Case Else
Call AppMessageBoxes(g_constrMODULE_AND_METHOD &
m_constrMODULE_NAME & g_constrDOUBLE_SPACE & constrROUTINE_NAME, _
vbExclamation + vbOKOnly +
vbMsgBoxSetForeground, g_constrERROR, , , Err)
End Select
End Sub
Public Sub AppMessageBoxes(ByVal strPrompt As String, _
ByVal lngButtons As Long, _
ByVal strTitle As String, _
Optional ByVal strHelpfile As String, _
Optional ByVal lngContext As Long, _
Optional ByVal objErr As Object, _
Optional ByRef intVal As Integer)
Const constrROUTINE_NAME As String = "AppMessageBoxes"
' There is no error trapping in this routine because
' error trapping will clear the error object that
' is passed to this error handling routine upon entrance
' On Error GoTo ErrorHandler
If Not objErr Is Nothing Then
Call MsgBox(g_constrERROR & objErr.Number & vbCr &
objErr.Description & vbCr & vbCr & strPrompt, _
lngButtons, strTitle)
' Log the error
If g_objThisAddIn.CurrentUser.PrintErrorLog = True Then
LogError strPrompt, objErr.Number, objErr.Description
End If
ElseIf intVal = 0 Then
intVal = MsgBox(strPrompt, lngButtons, strTitle)
Else
Call MsgBox(strPrompt, lngButtons, strTitle)
End If
Select Case Err.Number
Case 0 ' Do Nothing
' Unexpected error has occurred
Case Else
End Select
' Clear any unhandled errors
If Err.Number <> 0 Then
Err.Clear
End If
End Sub
Has anyone seen or does anyone know the cause of an err object's Number
property being reset when it is passed into a handling routine?
Technically, this should not happen because the object has not been
released from memory within the original calling routine.
Thanks & Regards,
Todd
Post by Jezebel
An error-handling routine should end with some form of resume statement,
otherwise your subsequent code is still within the error-handling context,
which screws up the handling of any further error. A better construction is
along these lines (remove the bits you don't need) --
Sub Something()
Const pFunctionName = "Something"
Dim pErrorResponse as long
On Error Goto Something_Error
' routine goes here
On error resume next
... function clean-up if any
Err.clear
Exit Sub
Select case err.number
Case vbObjectError
' special handling, if any
Case Else
pErrorResponse = Msgbox(err.description, vbIgnoreRetryCancel,
pFunctionName)
End Select
If pErrorResponse = vbRetry then Resume
If pErrorResponse = vbIgnore then Resume Next
Resume Something_Exit
End Sub
Hello,
I am experiencing an odd and intermittent problem with a COM addin that I've
built. I have seen this problem once before in a Word global template.
Sub Something
On Error Goto ErrorHandler
' routine goes here
If err.number <> 0 then
ErrorMessage err
end if
End Sub
Sub ErrorMessage(byval objErr as ErrObject)
msgbox "Error: " & objErr.Number & vbcr & "Description: " & objErr.Description
End Sub
If the above routine causes an error, the message box returned reveals
"Error: 0", i.e. no error, but this is not possible because otherwise, the
ErrorMessage routine would not be called.
I resolved this once before by passing in the err.number &
err.description
values as opposed to the err object itself. It was as if the OS was losing
its thread to the err object.
Has anyone else experienced this?
Regards,
TC
Joseph Geretz
2005-01-20 21:38:43 UTC
Permalink
Hi TC,
If a successful error object is passed into the routine, it clears it.
Not necessary. If you've gotten to this routine it means an error was
trapped and this function is being called from an Error Handler. The default
VB behavior is to clear the error when exiting from an Error Handler. You
don't need to do this at all. If you want to handle an error and then
reraise the error, then you need an Err.Raise in your Error Handler. But you
don't need an Err.Clear to suppress the error. That happens automatically
when you exit the Error Handler.

- Joe Geretz -
Hey Joseph,
A couple of final points.
I forgot to mention that the ErrorHandler in that message handler is not
actually dead at all. If a successful error object is passed into the
routine, it clears it. Also, if the "On Error Goto ErrorHandler" is
uncommented, it clears the object being passed in which defeats its purpose.
Also very interesting, I have been able to reproduce the behavior in a
demo app and if I put a breakpoint just prior to displaying the message
and view the objErr object in the Locals window, it displays the
appropriate information about the object. However, if I extract the
err.number & err.description and dump them in variables from within the
same routine, it works.
It only seems to lose its thread when the error message is actually called.
Very odd.
Regards,
Todd
Post by Joseph Geretz
Hi TC,
I've done quite a bit of work with VB error handling. I've seen the
symptom you describe when an error handler calls a method which has it's
own error trap (On Error statement) . For this reason we do very little
inside our own error handlers aside from calling a few of our own methods
which are specifically designed for use inside an error handler. (Similar
in concept to what you are doing. I see nothing wrong with this approach
per se.)
That being said, I see the commented On Error trap in your error handler
method, along with the error handler in that method which is ostensibly
never being called. I'm confused. Why comment out the error trap, and
retain a 'dead' error handler? Are you sure that the source code is
absolutely faithful to the binary in which you are seeing these symptoms?
Second, you seem to be missing an Exit Sub before your error handlers. I
see what you are trying to do by trapping for Err.Number = 0 in your
error handlers however typical code construction would prevent entry into
the handler to begin with unless an error has occurred. an Exit Sub just
before your handler will go a long way toward code clarity in this
respect.
Another interesting thing you are doing is passing the Err object as a
parameter. I wonder what effect that is having. In our error handling
methods we pass the Err properties we are interested in as separate
parameters (e.g. Err.Number, Err.Description, etc.).
Hope this helps,
- Joe Geretz -
Hey Jezebel,
I don't think that you under stood my question.
For what it's worth, your error handler does not need to be that
complicated nor do you need to repeat all of that code in all of your
routines.
' This routine removes all references, etc. and ends the current user session
Public Sub QuitSession()
Const constrROUTINE_NAME As String = "QuitSession"
On Error GoTo ErrorHandler
' If all objects have been destroyed, exit the routine
If g_objThisAddIn Is Nothing Then
GoTo ErrorHandler
End If
If Not g_objThisAddIn.Soap Is Nothing Then
With g_objThisAddIn.Soap
If .IsConnected = True Then
.SoapMethod = EndSession
.SoapMethodName = g_constrEND_SESSION
'disconnect the session!
.CallSoapMethod
.CompleteSoapCall
End If
End With
End If
' Save settings
SaveToolbarSettings
' Destroy addin instance
Set g_objThisAddIn = Nothing
Select Case Err.Number
Case 0 ' Do Nothing
' Unexpected error has occurred
Case Else
Call AppMessageBoxes(g_constrMODULE_AND_METHOD &
m_constrMODULE_NAME & g_constrDOUBLE_SPACE & constrROUTINE_NAME, _
vbExclamation + vbOKOnly +
vbMsgBoxSetForeground, g_constrERROR, , , Err)
End Select
End Sub
Public Sub AppMessageBoxes(ByVal strPrompt As String, _
ByVal lngButtons As Long, _
ByVal strTitle As String, _
Optional ByVal strHelpfile As String, _
Optional ByVal lngContext As Long, _
Optional ByVal objErr As Object, _
Optional ByRef intVal As Integer)
Const constrROUTINE_NAME As String = "AppMessageBoxes"
' There is no error trapping in this routine because
' error trapping will clear the error object that
' is passed to this error handling routine upon entrance
' On Error GoTo ErrorHandler
If Not objErr Is Nothing Then
Call MsgBox(g_constrERROR & objErr.Number & vbCr &
objErr.Description & vbCr & vbCr & strPrompt, _
lngButtons, strTitle)
' Log the error
If g_objThisAddIn.CurrentUser.PrintErrorLog = True Then
LogError strPrompt, objErr.Number, objErr.Description
End If
ElseIf intVal = 0 Then
intVal = MsgBox(strPrompt, lngButtons, strTitle)
Else
Call MsgBox(strPrompt, lngButtons, strTitle)
End If
Select Case Err.Number
Case 0 ' Do Nothing
' Unexpected error has occurred
Case Else
End Select
' Clear any unhandled errors
If Err.Number <> 0 Then
Err.Clear
End If
End Sub
Has anyone seen or does anyone know the cause of an err object's Number
property being reset when it is passed into a handling routine?
Technically, this should not happen because the object has not been
released from memory within the original calling routine.
Thanks & Regards,
Todd
Post by Jezebel
An error-handling routine should end with some form of resume statement,
otherwise your subsequent code is still within the error-handling context,
which screws up the handling of any further error. A better construction is
along these lines (remove the bits you don't need) --
Sub Something()
Const pFunctionName = "Something"
Dim pErrorResponse as long
On Error Goto Something_Error
' routine goes here
On error resume next
... function clean-up if any
Err.clear
Exit Sub
Select case err.number
Case vbObjectError
' special handling, if any
Case Else
pErrorResponse = Msgbox(err.description, vbIgnoreRetryCancel,
pFunctionName)
End Select
If pErrorResponse = vbRetry then Resume
If pErrorResponse = vbIgnore then Resume Next
Resume Something_Exit
End Sub
Hello,
I am experiencing an odd and intermittent problem with a COM addin that I've
built. I have seen this problem once before in a Word global template.
Sub Something
On Error Goto ErrorHandler
' routine goes here
If err.number <> 0 then
ErrorMessage err
end if
End Sub
Sub ErrorMessage(byval objErr as ErrObject)
msgbox "Error: " & objErr.Number & vbcr & "Description: " & objErr.Description
End Sub
If the above routine causes an error, the message box returned reveals
"Error: 0", i.e. no error, but this is not possible because otherwise, the
ErrorMessage routine would not be called.
I resolved this once before by passing in the err.number &
err.description
values as opposed to the err object itself. It was as if the OS was losing
its thread to the err object.
Has anyone else experienced this?
Regards,
TC
g***@mvps.org
2005-01-23 04:50:21 UTC
Permalink
Jezebel,

There are many weak links in the chain of my understanding of VBA.
Error handling is one of the weakest. Do you have or could you provide
an example of the techinque that you are advocating here? I am not
smart enough to know whether it is excessive or not. I would just like
to be able to step through it and then hopefully understand just what
is going on.

Tony Proctor
2005-01-20 11:55:57 UTC
Permalink
Despite the suggestions people have made here TX, there's nothing
fundamentally wrong with this code. It works fine on my own machine here.

The 'Err' object is a global one, though, and so can be modified by code
elsewhere, say when local objects are destroyed, or methods called on other
objects. Maybe something is resetting the global 'Err' object before you can
report on it. I'd recommend setting 'Break on All errors' in the IDE and
tracing through the exact sequence of events in your example.

Tony Proctor

"TC" <***@yahoo.com> wrote in message news:ujpHb$p$***@TK2MSFTNGP12.phx.gbl...
Hello,

I am experiencing an odd and intermittent problem with a COM addin that I've
built. I have seen this problem once before in a Word global template.

Imagine code structured like the following pseudo-code:

Sub Something
On Error Goto ErrorHandler

' routine goes here

ErrorHandler:

If err.number <> 0 then
ErrorMessage err
end if
End Sub

Sub ErrorMessage(byval objErr as ErrObject)
msgbox "Error: " & objErr.Number & vbcr & "Description: " &
objErr.Description
End Sub

If the above routine causes an error, the message box returned reveals
"Error: 0", i.e. no error, but this is not possible because otherwise, the
ErrorMessage routine would not be called.

I resolved this once before by passing in the err.number & err.description
values as opposed to the err object itself. It was as if the OS was losing
its thread to the err object.

Has anyone else experienced this?

Regards,

TC
Tom Winter
2005-01-20 14:35:56 UTC
Permalink
I agree with Tony. A couple thoughts on this problem that may or may not
help.

* I'm not sure if keeping a reference to the Err object will work. As Tony
said, I believe there is only one global Err object. You cannot really get a
copy of it that will keep its properties when other errors happen. I could
be wrong here, but I've never seen any code that tried to do that.

* ANY On Error ... statement will reset the global Err object to zero. That
means an On Error anywhere, in the another function, in another object,
anywhere in your code, or code you might be calling in a library.

* One of the real gotchas I've found is having objects terminate during
error handling when I wasn't expecting it. I would have On Error statements
in the Class_Terminate methods of some objects, and that would clear out the
values of the Err object, so basically my error would get lost. Since I had
to be able to deal with this (objects terminating during error handling), I
put code into the Class_Terminate methods that saved the Err properties
before I called On Error and then restored them at the end of the method. (I
do the same thing in a routine similar to your AppMessageBoxes.) I can share
some code if you like, though I agree with you that your current code
doesn't look like it could be suffering from this problem

I know it might not be to helpful, but my suggestion is to stop trying to
pass around the Err object. It's global anyway. There shouldn't be any need
to. That might get you started.
--
Tom Winter
Post by Tony Proctor
Despite the suggestions people have made here TX, there's nothing
fundamentally wrong with this code. It works fine on my own machine here.
The 'Err' object is a global one, though, and so can be modified by code
elsewhere, say when local objects are destroyed, or methods called on other
objects. Maybe something is resetting the global 'Err' object before you can
report on it. I'd recommend setting 'Break on All errors' in the IDE and
tracing through the exact sequence of events in your example.
Tony Proctor
Hello,
I am experiencing an odd and intermittent problem with a COM addin that I've
built. I have seen this problem once before in a Word global template.
Sub Something
On Error Goto ErrorHandler
' routine goes here
If err.number <> 0 then
ErrorMessage err
end if
End Sub
Sub ErrorMessage(byval objErr as ErrObject)
msgbox "Error: " & objErr.Number & vbcr & "Description: " & objErr.Description
End Sub
If the above routine causes an error, the message box returned reveals
"Error: 0", i.e. no error, but this is not possible because otherwise, the
ErrorMessage routine would not be called.
I resolved this once before by passing in the err.number & err.description
values as opposed to the err object itself. It was as if the OS was losing
its thread to the err object.
Has anyone else experienced this?
Regards,
TC
Ralph
2005-01-20 15:59:55 UTC
Permalink
Post by TC
Hello,
I am experiencing an odd and intermittent problem with a COM addin that
I've built. I have seen this
Post by TC
problem once before in a Word global template.
Sub Something
On Error Goto ErrorHandler
' routine goes here
If err.number <> 0 then
ErrorMessage err
end if
End Sub
Sub ErrorMessage(byval objErr as ErrObject)
msgbox "Error: " & objErr.Number & vbcr & "Description: " & objErr.Description
End Sub
If the above routine causes an error, the message box returned reveals
"Error: 0", i.e. no error, but this is not possible because otherwise, the
ErrorMessage routine would not be called.
I resolved this once before by passing in the err.number & err.description
values as opposed to the err object itself. It was as if the OS was losing
its
Post by TC
thread to the err object.
Has anyone else experienced this?
Regards,
TC
Although Tony's and Tom's advice is perhaps the better way to go - ie, don't
use an err object in the first place. I ran into this problem and solved it
a bit differently.

I moved the ErrorHandler function into a .bas module and declared it like
this...

Public Sub HandleError(ByRef oErr As Object, Optional ByRef sMsg As Variant
= "")
Dim sTmp As String
' Get VB Error Object's information
If oErr.Number Then
' format
sTmp = " Description : " & oErr.Description & vbCrLf & _
" Note : " & sMsg & vbCrLf & _
" VB Number : " & oErr.Number & vbCrLf & _
"Source/Module : " & oErr.Source
Else
sTmp = "Error Object Reset: " & sMsg
Debug.Assert False
End If
If gbVerbose Then MsgBox sTmp, vbOKOnly + vbCritical, "Error!"
If gbLogError Then LogErrorToDisk sTmp
Exit Sub
End Sub

Why a .bas module worked better than providing a class or form private
routine, or why declaring it as 'Object' instead of 'ErrObject' made a
difference is open to speculation, but within my problem domain the 'Reset'
errors went away.

hth
-ralph
TC
2005-01-20 20:45:57 UTC
Permalink
Hey Ralph, Tom & Tony,

Thanks for the info.

It appears that explanation lay in what all three have suggested (i.e. there
can be only one error object therefore passing it as an errObject may cause
problems).

That's interesting that passing it in as a generic object doesn't clear the
error.

Thanks for the explanation.

Regards,

TC
Post by TC
Post by TC
Hello,
I am experiencing an odd and intermittent problem with a COM addin that
I've built. I have seen this
Post by TC
problem once before in a Word global template.
Sub Something
On Error Goto ErrorHandler
' routine goes here
If err.number <> 0 then
ErrorMessage err
end if
End Sub
Sub ErrorMessage(byval objErr as ErrObject)
msgbox "Error: " & objErr.Number & vbcr & "Description: " &
objErr.Description
Post by TC
End Sub
If the above routine causes an error, the message box returned reveals
"Error: 0", i.e. no error, but this is not possible because otherwise, the
ErrorMessage routine would not be called.
I resolved this once before by passing in the err.number & err.description
values as opposed to the err object itself. It was as if the OS was losing
its
Post by TC
thread to the err object.
Has anyone else experienced this?
Regards,
TC
Although Tony's and Tom's advice is perhaps the better way to go - ie, don't
use an err object in the first place. I ran into this problem and solved it
a bit differently.
I moved the ErrorHandler function into a .bas module and declared it like
this...
Public Sub HandleError(ByRef oErr As Object, Optional ByRef sMsg As Variant
= "")
Dim sTmp As String
' Get VB Error Object's information
If oErr.Number Then
' format
sTmp = " Description : " & oErr.Description & vbCrLf & _
" Note : " & sMsg & vbCrLf & _
" VB Number : " & oErr.Number & vbCrLf & _
"Source/Module : " & oErr.Source
Else
sTmp = "Error Object Reset: " & sMsg
Debug.Assert False
End If
If gbVerbose Then MsgBox sTmp, vbOKOnly + vbCritical, "Error!"
If gbLogError Then LogErrorToDisk sTmp
Exit Sub
End Sub
Why a .bas module worked better than providing a class or form private
routine, or why declaring it as 'Object' instead of 'ErrObject' made a
difference is open to speculation, but within my problem domain the 'Reset'
errors went away.
hth
-ralph
Martin Seelhofer
2005-01-21 10:54:37 UTC
Permalink
Hey TC
Post by TC
That's interesting that passing it in as a generic object doesn't clear
the error.
Well, apart from passing it in as of type Object there's another - from my
point of view more significant - difference in Ralph's code and in yours.
While you pass the err object ByVal and therefore make a copy of the
global reference err, Ralph did that ByRef and therefore passes in the
global reference err itself (internally by passing a pointer to the
reference
err).

It seems to me that the implementation of VBA error handling and the
global err-object does not to like competition ;-)


Cheers,
Martin
Tony Proctor
2005-01-21 11:20:26 UTC
Permalink
ByVal passes an object body by reference, and ByRef passes an object
reference by reference Martin. Hence, the same object is being passed in
both instances. See
http://www.google.ie/groups?safe=off&as_umsgid=%***@TK2MSFTNGP12.phx.gbl&lr=lang_en&hl=en

Tony Proctor
Post by Martin Seelhofer
Hey TC
Post by TC
That's interesting that passing it in as a generic object doesn't clear
the error.
Well, apart from passing it in as of type Object there's another - from my
point of view more significant - difference in Ralph's code and in yours.
While you pass the err object ByVal and therefore make a copy of the
global reference err, Ralph did that ByRef and therefore passes in the
global reference err itself (internally by passing a pointer to the
reference
err).
It seems to me that the implementation of VBA error handling and the
global err-object does not to like competition ;-)
Cheers,
Martin
Martin Seelhofer
2005-01-21 13:31:52 UTC
Permalink
Hi Tony
Post by Tony Proctor
ByVal passes an object body by reference, and ByRef passes an object
reference by reference Martin. Hence, the same object is being passed in
both instances. See [...]
Thanx for trying to clear things up (and thanx for the link). However,
you might still agree with me that, to be picky, there's a difference
between duplicating the object reference (pointer, ByVal) and passing
in a pointer to the object reference (pointer to pointer, ByRef). Depending
on the internal object realization (reference counting etc.), there might
actually be quite a difference (from my point of view that is)...


Cheers,
Martin
Tony Proctor
2005-01-21 14:41:56 UTC
Permalink
I agree that something is odd is going on if the 'Object' declaration works,
although I don't profess to understand why. As to whether a *.bas/*.cls
makes a difference, or Object/ErrObject, or ByVal/ByRef, I can't say since I
still don't have a reproducible case.

However, since the Err object is global to each module (EXE/DLL/OCX - but
not the whole project or process), I tend to avoid this situation anyway.

In general, I make a copy of my Err object before attempting any error
cleanup or reporting. I then use my copy in the knowledge that any
subsequent error is free to use the prevailing Err object.

Tony Proctor
Post by Martin Seelhofer
Hi Tony
Post by Tony Proctor
ByVal passes an object body by reference, and ByRef passes an object
reference by reference Martin. Hence, the same object is being passed in
both instances. See [...]
Thanx for trying to clear things up (and thanx for the link). However,
you might still agree with me that, to be picky, there's a difference
between duplicating the object reference (pointer, ByVal) and passing
in a pointer to the object reference (pointer to pointer, ByRef). Depending
on the internal object realization (reference counting etc.), there might
actually be quite a difference (from my point of view that is)...
Cheers,
Martin
Loading...