On error resume next

This thread seems so wrong on so many levels. Wishing for VB-like ‘error
handling’ is… well… its quite beyond my comprehension. If you really want
to achieve the implied behaviour of the piece of pseudo-code above, try:
def test
begin
conn=adodb.connection
conn.open …
rescue ADatabaseError
conn = nil
end
if conn.nil? then
#add data to file
else
#add data to db
end
ensure
conn.Close unless conn.nil?
end

But I think you really have to ask yourself, will this give me a good system
state if some random error can throw my (logging/ reporting/ whatever DB is
supposed to hold) to file at any random moment? How do you later reconcile
the DB and file? If this is supposed to be a program level switch, write a
DoWhateverImDoingToStoreData class that can polymorphically write to file or
database depending on a factory level switch, and pick it at runtime - to
switch mid program as the result of an error seems like folly.

YMMV

David Naseby

···

-----Original Message-----
From: Shannon Fang [mailto:xrfang@hotmail.com]

I tried to do the following: (peudo-code)

def test
begin
conn=adodb.connection
conn.open …
if conn!=nil then
#add data to db
else
#add data to file
end
rescue DBError
conn=nil
resume next
end
end

i don’t quite understand this… the next WHAT? where is
the implied loop
supposed to be?

The benefit of resume next is that it will catch all errors. Here, I
expect error to happen on the conn.open statement., so if error happen,
set conn=nil.

I can’t express how I feel :frowning: The code below is just ONE of its usage,
something else in my mind is:

begin
# do whatever you want to do
rescue Error A
#fix error
retry
rescue Error B
resume next
rescue
printe “I can’t fix your error”
end

In the above, between begin … rescue Error A, any possible Error can
occur, if you don’t have resume next mechanism, you need to wrap the
begin end block around the place that the error may occur, multi times.

Please do not misunderstand, and discuss “how to reconcile database and
disk file”. The following task is just a SAMPLE. In some critical tasks,
you may want to ignore some trivial errors and continue. For example, if
you run a web server, you don’t want to find out in the morning that
your server was shut down for 10 hours just because it can’t write into
the weblog file…

Thanks!
Shannon

···

On Fri, 6 Dec 2002 11:43:29 +0900 David Naseby david.naseby@eonesolutions.com.au wrote:

-----Original Message-----
From: Shannon Fang [mailto:xrfang@hotmail.com]

I tried to do the following: (peudo-code)

def test
begin
conn=adodb.connection
conn.open …
if conn!=nil then
#add data to db
else
#add data to file
end
rescue DBError
conn=nil
resume next
end
end

i don’t quite understand this… the next WHAT? where is
the implied loop
supposed to be?

The benefit of resume next is that it will catch all errors. Here, I
expect error to happen on the conn.open statement., so if error happen,
set conn=nil.

This thread seems so wrong on so many levels. Wishing for VB-like ‘error
handling’ is… well… its quite beyond my comprehension. If you really want
to achieve the implied behaviour of the piece of pseudo-code above, try:
def test
begin
conn=adodb.connection
conn.open …
rescue ADatabaseError
conn = nil
end
if conn.nil? then
#add data to file
else
#add data to db
end
ensure
conn.Close unless conn.nil?
end

But I think you really have to ask yourself, will this give me a good system
state if some random error can throw my (logging/ reporting/ whatever DB is
supposed to hold) to file at any random moment? How do you later reconcile
the DB and file? If this is supposed to be a program level switch, write a
DoWhateverImDoingToStoreData class that can polymorphically write to file or
database depending on a factory level switch, and pick it at runtime - to
switch mid program as the result of an error seems like folly.

YMMV

David Naseby

People have managed to implement extremely robust recovery logic
without relying on a VB-style “resume next”, though. The problem
with “resume next” is that, ultimately, it’s nondeterministic.
(There are cases when Error B is thrown that you may NOT want to
resume next. Because of the nondeterminism behind your sample above,
there’s really no way to properly handle that.)

What I’m PERSONALLY suggesting is that you may want to reconsider
how you’re designing your program. To me, needing a “resume next”
feature suggests that there’s something broken with the program’s
model and it needs fixing. Exceptions should be handled “locally”
and not propagated upwards; by locally, I mean as close to the
possible source of the exception as possible. Exceptions are only
propagated upwards if they aren’t able to be handled at the level
you’re dealing with them.

I’ve also (personally) found that there’s no good “generic” error
handling, which is essentially what you’re asking for. You can
simulate it in some cases by doing:

foo rescue op = handle_error
case op
when …
end

It doesn’t do much better than a properly localized
begin/rescue/end block, but it may be preferable for your program’s
implementation.

-austin
– Austin Ziegler, austin@halostatue.ca on 2002.12.06 at 07.28.43

···

On Fri, 6 Dec 2002 15:55:31 +0900, Shannon Fang wrote:

I can’t express how I feel :frowning: The code below is just ONE of its
usage, something else in my mind is:

begin

do whatever you want to do

rescue Error A

fix error

retry
rescue Error B
resume next
rescue
printe “I can’t fix your error”
end

In the above, between begin … rescue Error A, any possible Error
can occur, if you don’t have resume next mechanism, you need to
wrap the begin end block around the place that the error may
occur, multi times.

Shannon Fang wrote:

I can’t express how I feel :frowning: The code below is just ONE of its usage,
something else in my mind is:

begin

do whatever you want to do

rescue Error A
#fix error
retry
rescue Error B
resume next
rescue
printe “I can’t fix your error”
end

Part of the problem here is that what happens if the magic line of code
call #fix error didn’t work. You would just go into a loop. If you can
fix an error then why dont you do some checks upfront to make sure it is
going to work in the first place?

In your example you do not need to rescue Error B as the third rescue
will catch the error and then the program will carry on after the end
and execute the next available statement.