Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
DiscussionsAccessExcelInfoPathOutlookPowerPointPublisherWord
DirectoryUser Groups
Related Topics
Outlook ExpressInternet ExplorerWindowsMS Server ProductsMore Topics ...

MS Office Forum / Word / Programming / December 2006

Tip: Looking for answers? Try searching our database.

I thought that I had a basic understanding of errors

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Greg Maxey - 04 Dec 2006 00:07 GMT
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.
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.