Smart solution for abort/retry/ignore error handling

N

Nimral

Hi folks,

is there a smart way to develop efficiently that helps me in the
following situation: a sub calls a subsub, which calls a subsubsub,
and so on.

Within a subsubsub an error occurs which I handle, either using on
error goto / err.number, or a try... catch block. I display a msgbox
(abort,retry,ignore). Implementing retry and ignore is fairly easy
using a loop structure. But how about "abort"?

First of all I do not, of course, want to terminate the whole
application using an end statement.

What I would want ist to continume execution somewhere near the end of
the sub where the chain of calls originated, do some cleanup work, and
then resume the main form routine of my program.

Cleanly terminating each sub until I reach the originating sub ist a
lot of clumsy code.

I have seen that try ... catch blocks come pretty close to what I have
in mind, but I haven't figured out yet wether I can simply use one by
willingly triggering the catched exception somewhere in a sub-sub (if
so ... how is this done), or wether there is another way to get what I
want.

Thanks,

Armin.
 
O

\(O\)enone

Nimral said:
Within a subsubsub an error occurs which I handle, either using on
error goto / err.number, or a try... catch block. I display a msgbox
(abort,retry,ignore). Implementing retry and ignore is fairly easy
using a loop structure. But how about "abort"?

How about creating yourself a new exception class, perhaps an
ApplicationAbortException.

Then when the user selects to abort, you can throw a new
ApplicationAbortException up to the calling procedure.

Each procedure which has an exception handler should specifically try to
catch ApplicationAbortExceptions, and if one is caught it can perform
whatever tidying up is required, and then re-throw the exception back up to
its calling procedure.

Would that do what you want?

Alternatively, you could abort your app by using a call to
Application.Exit(), and then put all your tidy up code inside Finally blocks
(which is where it should be anyway, of course). Application.Exit()
provides a quick way of closing your application, but unlike the End
statement (which IMO is evil and should never be used) it does ensure that
all the Finally blocks are called.
 
N

Nimral

Hi OneOne,

the good I have, with some trial, found a code that works, but I
don't quite understand why, and don't know wether I get unwanted side
effects.

This is the code.

Module Module1

Dim exAbort As Exception

Function ErrorHandler(ByVal strMessage)

ErrorHandler = MsgBox(strMessage, vbAbortRetryIgnore)
If ErrorHandler = vbAbort Then
Throw exAbort
End If
End Function

Sub RemoveDirectory(ByVal strPath As String)

' Remove a directory

Dim iControl
Do
iControl = vbIgnore
Try
System.IO.Directory.Delete(strPath)
Catch ex As Exception
iControl = ErrorHandler("Cannot remove directory: " &
strPath)
End Try
Loop Until (iControl = vbIgnore)
End Sub

Sub Main()

Try
RemoveDirectory("c:\temp\xxx\yyy\zzz")
MsgBox("Directory removed (or error ignored)")
Catch ex As Exception
MsgBox("Directory remove: Abort Pressed!")
Finally
MsgBox("Cleanup!")
End Try
End Sub

End Module

It does attempt to remove a directory "c:\temp\xxx\yyy\zzz" and
implements abort/retry/ignore error handling through the ErrorHandler
function in case of an error like "directory does not exist".
Each procedure which has an exception handler should specifically try to
catch ApplicationAbortExceptions, and if one is caught it can perform
whatever tidying up is required, and then re-throw the exception back up to
its calling procedure.

Could not yet find out how to define and trigger my own exceptions.
the above sample triggers the catch block of the main sub, obviously
because the exception is thrown within the catch block of the
RemoveDirectory routine. I assume that throwing an exception from
within the catch block of another try block does always invoke the
catch block of the preceding try block, right? So my main routine does
not catch specific errors triggered by my errorhandler, but any error
triggered from within subroutines that are unhandled.

Now since my program is very strictly structured, I could probably get
away with this approcach, but it isn't quite what you suggested.

Another problem was the declaration of Dim exAbort As Exception. As
soon as I realized that I'd trigger the catch block of the main () sub
regardless of which I name I was going to give the exception, I tried
to put the declaration right at the beginning of the ErrorHandler sub.
This would not compile.

I did also try to use the declaration and throw code like above, but
pu a statement like

catch exAbort

into the main sub, to make clear that I want to catch only exAbort
Exceptions, but this did not compile as well, VB forced me to

Catch ex As Exception

My global "Dim exAbort As Exception" statement makes the code compile,
but doesn't make much sense otherwise, and first of all it does not
obviously reference the catch block in the main routine, so the code
isn't very readable.

Can you help me a step forward, or point my nose to a piece of doc
that helps me understand all this? I found tons of docs about simple
try/catch blocks, but they all deal with local exception handling
within a subroutine, and none came close to what I have here.

Thanks,

Armin.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top