PDA

View Full Version : Python exceptions: retry on transient errors



mssever
April 23rd, 2008, 07:33 AM
Suppose I get an exception due to a transient error such as a network glitch. In Ruby, I might do something like this:

counter = 0
begin
foo.bar
rescue SomeTransientError
counter += 1
if counter < 10
retry
else
raise
end
endWhere retry jumps to the begin. What's the recommended way to do this in Python?

ghostdog74
April 23rd, 2008, 08:22 AM
Suppose I get an exception due to a transient error such as a network glitch. In Ruby, I might do something like this:

counter = 0
begin
foo.bar
rescue SomeTransientError
counter += 1
if counter < 10
retry
else
raise
end
endWhere retry jumps to the begin. What's the recommended way to do this in Python?



try
...
except Exception,e:
...

Quikee
April 23rd, 2008, 09:03 AM
Suppose I get an exception due to a transient error such as a network glitch. In Ruby, I might do something like this:

counter = 0
begin
foo.bar
rescue SomeTransientError
counter += 1
if counter < 10
retry
else
raise
end
endWhere retry jumps to the begin. What's the recommended way to do this in Python?



counter = 0
while counter < 10:
try:
foo.bar
except SomeTransientError:
counter += 1
if counter >= 10:
raise
:)

RIchard James13
April 23rd, 2008, 09:22 AM
Maybe like this

fails = 0
passed = 0
while passed==0 or fails<10:
try:
someFunctionThatFails()
passed=1
except:
fails+=1

if passed!=1:
raise someException

RIchard James13
April 23rd, 2008, 09:26 AM
counter = 0
while counter < 10:
try:
foo.bar
except SomeTransientError:
counter += 1
if counter >= 10:
raise
:)

Actually I thought of that but then realised that if the exception is never triggered then foo.bar will be called forever.

I think what we want here is
Function is called
If it errors then retry up to ten times
Else continue with the program

Quikee
April 23rd, 2008, 12:30 PM
Actually I thought of that but then realised that if the exception is never triggered then foo.bar will be called forever.

Damn.. I totally overlooked this case. ;)

mssever
April 23rd, 2008, 04:20 PM
So Python basically makes you use a while loop? I suspected that that might be the case, but I was hoping I was wrong. Ruby's retry statement can be very handy sometimes.

mssever
April 23rd, 2008, 04:30 PM
Here's what I ended up with:

counter = 0
while True:
try:
foo.bar()
break
except TransientError:
counter += 1
if counter > 10:
raise

Quikee
April 23rd, 2008, 05:17 PM
There is also an alternative way but I don't know if you will like it:



def foo():
raise Exception, "eeeee"

def retryFunction():
foos = [foo] * 10
for eachFoo in foos:
try:
eachFoo()
except Exception:
pass
else:
return
raise
retryFunction()

mssever
April 23rd, 2008, 06:36 PM
There is also an alternative way but I don't know if you will like it:



def foo():
raise Exception, "eeeee"

def retryFunction():
foos = [foo] * 10
for eachFoo in foos:
try:
eachFoo()
except Exception:
pass
else:
return
raise
retryFunction()

That seems overly complicated to me.

I ended up modifying my solution slightly.

counter = 0
while True:
try:
foo.bar()
except TransientError:
counter += 1
if counter > 10:
raise
else:
break

Quikee
April 23rd, 2008, 09:20 PM
That seems overly complicated to me.

I ended up modifying my solution slightly.

counter = 0
while True:
try:
foo.bar()
except TransientError:
counter += 1
if counter > 10:
raise
else:
break

Yeah.. but it would still work if you would do it this way:


def foo(i):
print i
raise Exception, "eeeee"

def try10():
for i in xrange(10):
try:
return foo(i)
except Exception:
pass
raise

try10()

I believe it is a neater but not so obvious solution.

Can+~
April 23rd, 2008, 09:27 PM
Yeah.. but it would still work if you would do it this way:


def foo(i):
print i
raise Exception, "eeeee"

def try10():
for i in xrange(10):
try:
return foo(i)
except Exception:
pass
raise

try10()

I believe it is a neater but not so obvious solution.

But that would do 10 repetitions, even if it works. I know that you could add a break statement, but I prefer the one posted by mssever.

Quikee
April 23rd, 2008, 10:03 PM
But that would do 10 repetitions, even if it works. I know that you could add a break statement, but I prefer the one posted by mssever.

No .. if it works it will exit the function as there is a "return foo(i)" - foo function doesn't need to return anything for this to work. A break wouldn't work as you would break the for loop and would trigger raise which would raise the last exception occurred. ;) I agree that it might not be the most readable and obvious solution as it is a little bit evil.