Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Repeat Python function call on exception?

Tags:

python

Hey everybody I'm working on a data scraping project and I'm looking for a clean way to repeat a function call if an exception is raised.

Pseudo-code:

try:
    myfunc(x)
except myError:
    ###try to call myfunc(x) again Y number of times, 
        until success(no exceptions raised) otherwise raise myError2

I realize this isn't best practice at all but I'm working through a number of different code/network layers that aren't reliable and I can't realistically debug them.

Right now I'm accomplishing this with a huge set of try\except blocks and it's making my eyes bleed.

Elegant ideas anyone?

like image 619
Haipa Avatar asked Jan 22 '11 06:01

Haipa


3 Answers

To do precisely what you want, you could do something like the following:

import functools
def try_x_times(x, exceptions_to_catch, exception_to_raise, fn):
    @functools.wraps(fn) #keeps name and docstring of old function
    def new_fn(*args, **kwargs):
        for i in xrange(x):
            try:
                return fn(*args, **kwargs)
            except exceptions_to_catch:
                 pass
        raise exception_to_raise
    return new_fn

Then you just wrap the old function in this new function:

#instead of
#risky_method(1,2,'x')
not_so_risky_method = try_x_times(3, (MyError,), myError2, risky_method)
not_so_risky_method(1,2,'x')

#or just
try_x_times(3, (MyError,), myError2, risky_method)(1,2,'x')
like image 80
user470379 Avatar answered Sep 19 '22 21:09

user470379


Use a loop

i = 0
while True:
  try: myfunc(x); break;
  except myError:
    i = i + 1;
    # print "Trying again"
    if i > 5: raise myError2;
like image 44
Ming-Tang Avatar answered Sep 18 '22 21:09

Ming-Tang



for x in xrange(num_retries):
    try:
        myFunc()
    except MyError, err:
        continue
        #time.sleep(1)
    err = None
    break
if err:
    raise MyError2
#else:
#    print "Success!"


like image 45
primroot Avatar answered Sep 17 '22 21:09

primroot