Can someone help me understand why TestA works and TestB and TestC do not:
Sub TestA()
On Error Resume Next
Err.Raise 6
On Error GoTo SubErr:
Err.Raise 13
SubErr:
MsgBox "Eureka!!"
End Sub
Sub TestB()
On Error GoTo Err_Handler
Err.Raise 6
Err_Handler:
On Error GoTo SubErr:
Err.Raise 13
SubErr:
MsgBox "Eureka!!"
End Sub
Sub TestC()
On Error GoTo Err_Handler
Err.Raise 6
Err_Handler:
On Error Resume Next
Err.Raise 13
MsgBox "Eureka!!"
End Sub
In TestB and TestC, I have tried about every combination of GoTo, Resume, Err.Clear, that I can think of. I don't understand why the code isn't handling the second error. thanks.

Signature
Greg Maxey/Word MVP
See:
http://gregmaxey.mvps.org/word_tips.htm
For some helpful tips using Word.
Jezebel - 04 Dec 2006 01:20 GMT
Not sure quite what you mean by 'working' in respect of TestA -- it ignores the first error, and jumps to SubErr for the second.
But the big issue, is that none of your error-handlers actually 'handles' the error. An error is handled when the function exits or you execute a resume or resume [label] instruction. Until you do that, the code is still running within the context of the original-handler, and any further errors are passed 'up the line' to an error-handler in the calling function, if there is one. So a) the error-handler can't deal with errors within the error-handler itself, and b) you can't issue a new 'on error goto ...' within the context of the error-handling code. Try this --
Sub TestA()
On Error GoTo SubErr:
TestB
SubErr:
MsgBox "Error in Test A"
End Sub
Sub TestB()
On Error GoTo Err_Handler
Err.Raise 6
Err_Handler:
On Error GoTo Err_Handler:
MsgBox "Error in TestB"
Err.Raise 13
End Sub
The moral is, don't try to do clever things in the error-handling code: just handle the error and resume, either back to the code or to the exit point.
Can someone help me understand why TestA works and TestB and TestC do not:
Sub TestA()
On Error Resume Next
Err.Raise 6
On Error GoTo SubErr:
Err.Raise 13
SubErr:
MsgBox "Eureka!!"
End Sub
Sub TestB()
On Error GoTo Err_Handler
Err.Raise 6
Err_Handler:
On Error GoTo SubErr:
Err.Raise 13
SubErr:
MsgBox "Eureka!!"
End Sub
Sub TestC()
On Error GoTo Err_Handler
Err.Raise 6
Err_Handler:
On Error Resume Next
Err.Raise 13
MsgBox "Eureka!!"
End Sub
In TestB and TestC, I have tried about every combination of GoTo, Resume, Err.Clear, that I can think of. I don't understand why the code isn't handling the second error. thanks.
--
Greg Maxey/Word MVP
See:
http://gregmaxey.mvps.org/word_tips.htm
For some helpful tips using Word.
Jay Freedman - 04 Dec 2006 01:23 GMT
Hi Greg,
I'll quote the Remarks section of the help topic for the On Error
statement:
"If an error occurs while an error handler is active (between the
occurrence of the error and a Resume, Exit Sub, Exit Function, or Exit
Property statement), the current procedure's error handler can't
handle the error. Control returns to the calling procedure. If the
calling procedure has an enabled error handler, it is activated to
handle the error. If the calling procedure's error handler is also
active, control passes back through previous calling procedures until
an enabled, but inactive, error handler is found. If no inactive,
enabled error handler is found, the error is fatal at the point at
which it actually occurred."
Looking at your examples, TestA only has one handler and it's
triggered by the Err.Raise 13. That is, the Resume Next doesn't count
as an "active error handler". In TestB and TestC, you're trying to
catch an error while you're already inside an active error handler,
and that isn't allowed.
To see what the help is talking about wrt a calling procedure, try
single-stepping with F8 through this code, starting in TestD:
Sub TestD()
On Error GoTo Err_HandlerD
Call TestE
Exit Sub
Err_HandlerD:
MsgBox "D: Eureka!! (" & Err.Number & ")"
End Sub
'~~~~~~~~~~~~
Sub TestE()
On Error GoTo Err_HandlerE
Err.Raise 6
Exit Sub
Err_HandlerE:
On Error GoTo SubErr
Err.Raise 13
Exit Sub
SubErr:
MsgBox "E: Eureka (" & Err.Number & ")!!"
End Sub
At a language-design level, I think this restriction was put into VBA
to avoid having to deal with some nasty issues. You can easily get
into infinite loops when you allow error-handling that itself can
cause errors. OTOH, there are legitimate circumstances where you want
to do something of this sort -- for example, if an error occurs and
you want to log it, but you get an error from the OS when you try to
open the log file. There are ways to handle that with only On Error
Resume Next.
--
Regards,
Jay Freedman
Microsoft Word MVP FAQ: http://word.mvps.org
Email cannot be acknowledged; please post all follow-ups to the
newsgroup so all may benefit.
>Can someone help me understand why TestA works and TestB and TestC do not:
>
[quoted text clipped - 27 lines]
>
>In TestB and TestC, I have tried about every combination of GoTo, Resume, Err.Clear, that I can think of. I don't understand why the code isn't handling the second error. thanks.
Greg Maxey - 04 Dec 2006 12:52 GMT
Thanks Gents,
I did reply last night, but see this morning that it didn't transmit.
I have had a few error messages the past two days using OE that
newsgroups coudn't be resolved?
Anyway, thanks for both replies. Jezebel, by working I just meant the
code would run without generating a runtime error. With your reply and
Jay's I see now why it would and the others wouldn't. It was a poor
example.
The basic problem was this. I wanted an error handler that when an
error was generated that it would simply ignore it an go on to save the
document. I was working with TestA below which worked OK except when
the user canceled or "X" out of the SaveAs Dialog. It would then throw
and error while in the error handler.
Sub TestA()
On Error GoTo Err_Handler
MsgBox ActiveDocument.Bookmarks(1).Range.Text
'Other Stuff
Exit Sub
Err_Handler:
ActiveDocument.Save
End Sub
I can work throug that issue using this construction. Do either of you
see problems with this method? Thanks.
Sub TestB()
On Error GoTo Err_Handler
MsgBox ActiveDocument.Bookmarks(1).Range.Text
'Other Stuff
Exit Sub
Err_ReEntry:
On Error Resume Next
ActiveDocument.Save
Exit Sub
Err_Handler:
Resume Err_ReEntry
End Sub
> Can someone help me understand why TestA works and TestB and TestC do not:
>
[quoted text clipped - 64 lines]
>
> ------=_NextPart_000_0026_01C7170E.4D45F5C0--
Jay Freedman - 04 Dec 2006 14:49 GMT
> Thanks Gents,
>
[quoted text clipped - 37 lines]
> Resume Err_ReEntry
> End Sub
Your TestB will work, and that style is common. But I personally find it
nonlinear and unintuitive, sending execution down to the bottom of the code
only to make it jump back to the point of the error. Besides that, if there
are multiple places in the routine that could trigger several different
kinds of errors, they all wind up going through Err_Handler and back to
wherever the error was. It can be a nightmare to debug, especially with
data-dependent errors.
I prefer a more linear and localized style, like this:
Sub TestJ()
On Error Resume Next
MsgBox ActiveDocument.Bookmarks(1).Range.Text
If Err.Number > 0 Then ' or just If Err.Number Then
Err.Clear
ActiveDocument.Save
Exit Sub
End If
'Other Stuff
End Sub
Each statement that could trigger an error can have a separate "error
handler" within an If Err.Number .. End If clause that immediately follows
that statement. You can nest these If clauses, one within another. If one
statement could trigger several kinds of errors, you can replace the simple
If clause with an If Err.Number = X .. ElseIf Err.Number = Y .. End If or a
Select Case Err.Number statement to do different things for different
errors. [If you program in other languages, you may recognize this style as
VBA's dumbed-down version of Try .. Catch blocks.]

Signature
Regards,
Jay Freedman
Microsoft Word MVP FAQ: http://word.mvps.org
Email cannot be acknowledged; please post all follow-ups to the newsgroup so
all may benefit.
Greg Maxey - 04 Dec 2006 15:24 GMT
Thanks Jay,
> > Thanks Gents,
> >
[quoted text clipped - 74 lines]
> Email cannot be acknowledged; please post all follow-ups to the newsgroup so
> all may benefit.