Good exception handling when retrying code

I have some test cases. In test cases, data that takes time to calculate is relied upon. To speed up testing, I cached the data so that it did not need to be recounted.

Now I have foo()one that looks at cached data. I canโ€™t say in advance what he will look at, since it depends on the test case.

If the test case does not work, it does not find the correct cached data, I do not want it to fail - I want it to calculate the data, and then try again. I also do not know which exception, in particular, it will cause the lack of data.

My code now looks like this:

if cacheExists:
    loadCache()
    dataComputed = False
else:
    calculateData()
    dataComputed = True

try:
    foo()
except:
    if not dataComputed:
        calculateData() 
        dataComputed = True
        try:
            foo()
        except:
            #error handling code
    else:
        #the same error handling code

What is the best way to restructure this code?

+3
5

, Python, , , ++ Java, - Python, , " , " ( , , , ). , except - ( , , raise, ). , , , , :

expected_exceptions = KeyError, AttributeError, TypeError

except expected_exceptions:, except:.

, , :

try:
    foo1()
except expected_exceptions:
    try:
        if condition:
            foobetter()
        else:
            raise
    except expected_exceptions:
        handleError()

try/except:

def may_raise(expected_exceptions, somefunction, *a, **k):
  try:
    return False, somefunction(*a, **k)
  except expected_exceptions:
    return True, None

, - "". , ( , ), :

failed, _ = may_raise(expected_exceptions, foo1)
if failed and condition:
  failed, _ = may_raise(expected_exceptions, foobetter)
if failed:
  handleError()

, , , . , , may_raise, , ( , , , ); ...! -)

+4

. ? KeyError, AttributeError, TypeError...

, , - hasattr() in , , .

, , !

+1

, . foo() :

if cacheExists:
    loadCache()
    dataComputed = False
else:
    calculateData()
    dataComputed = True

while True:
    try:
        foo()
        break
    except:
        if not dataComputed:
            calculateData()
            dataComputed = True
            continue 
        else:
            #the error handling code
            break

, YMMV...

:

if cacheExists:
    loadCache()
    dataComputed = False
else:
    calculateData()
    dataComputed = True

done = False
while !done:
    try:
        foo()
        done = True
    except:
        if not dataComputed:
            calculateData()
            dataComputed = True
            continue 
        else:
            #the error handling code
            done = True
+1

, .

may_raise. , !

def foo(x):
    raise Exception("Arrrgh!")
    return 0

def foobetter(x):
    print "Hello", x
    return 1

def try_many(functions, expected_exceptions, *a, **k):
    ret = None
    for f in functions:
        try:
            ret = f(*a, **k)
        except expected_exceptions, e:
            print e
        else:
            break
    return ret

print try_many((foo, foobetter), Exception, "World")

Arrrgh!
Hello World
1
+1

, foobetter() ? , , - (!). .

0

Source: https://habr.com/ru/post/1716248/


All Articles