Catch exception and continue try block in Python

Question:

Can I return to executing the try block after exception occurs?

For example:

try:
    do_smth1()
except:
    pass

try:
    do_smth2()
except:
    pass

vs.

try:
    do_smth1()
    do_smth2()
except:
    ??? # magic word to proceed to do_smth2() if there was exception in do_smth1
Asked By: igor

||

Answers:

No, you cannot do that. That’s just the way Python has its syntax. Once you exit a try-block because of an exception, there is no way back in.

What about a for-loop though?

funcs = do_smth1, do_smth2

for func in funcs:
    try:
        func()
    except Exception:
        pass  # or you could use 'continue'

Note however that it is considered a bad practice to have a bare except. You should catch for a specific exception instead. I captured for Exception because that’s as good as I can do without knowing what exceptions the methods might throw.

Answered By: user2555451

You could iterate through your methods…

for m in [do_smth1, do_smth2]:
    try:
        m()
    except:
        pass
Answered By: David Neale

I don’t think you want to do this. The correct way to use a try statement in general is as precisely as possible. I think it would be better to do:

try:
    do_smth1()
except Stmnh1Exception:
    # handle Stmnh1Exception

try:
    do_smth2()
except Stmnh2Exception:
    # handle Stmnh2Exception
Answered By: rlms

Depending on where and how often you need to do this, you could also write a function that does it for you:

def live_dangerously(fn, *args, **kw):
    try:
        return fn(*args, **kw)
    except Exception:
        pass

live_dangerously(do_smth1)
live_dangerously(do_smth2)

But as other answers have noted, having a null except is generally a sign something else is wrong with your code.

Answered By: Dan

You can achieve what you want, but with a different syntax. You can use a “finally” block after the try/except. Doing this way, python will execute the block of code regardless the exception was thrown, or not.

Like this:

try:
    do_smth1()
except:
    pass
finally:
    do_smth2()

But, if you want to execute do_smth2() only if the exception was not thrown, use a “else” block:

try:
    do_smth1()
except:
    pass
else:
    do_smth2()

You can mix them too, in a try/except/else/finally clause.
Have fun!

Answered By: Lucas Ribeiro

one way you could handle this is with a generator. Instead of calling the function, yield it; then whatever is consuming the generator can send the result of calling it back into the generator, or a sentinel if the generator failed: The trampoline that accomplishes the above might look like so:

def consume_exceptions(gen):
    action = next(gen)
    while True:
        try:
            result = action()
        except Exception:
            # if the action fails, send a sentinel
            result = None

        try:
            action = gen.send(result)
        except StopIteration:
            # if the generator is all used up, result is the return value.
            return result

a generator that would be compatible with this would look like this:

def do_smth1():
    1 / 0

def do_smth2():
    print "YAY"

def do_many_things():
    a = yield do_smth1
    b = yield do_smth2
    yield "Done"
>>> consume_exceptions(do_many_things())
YAY

Note that do_many_things() does not call do_smth*, it just yields them, and consume_exceptions calls them on its behalf

While the other answers and the accepted one are correct and should be followed in real code, just for completeness and humor, you can try the fuckitpy ( https://github.com/ajalt/fuckitpy ) module.

Your code can be changed to the following:

@fuckitpy
def myfunc():
    do_smth1()
    do_smth2()

Then calling myfunc() would call do_smth2() even if there is an exception in do_smth1())

Note: Please do not try it in any real code, it is blasphemy

Answered By: pankaj

special_func to avoid try-except repetition:

def special_func(test_case_dict):
    final_dict = {}
    exception_dict = {}

    def try_except_avoider(test_case_dict):

        try:
            for k,v in test_case_dict.items():
                final_dict[k]=eval(v) #If no exception evaluate the function and add it to final_dict

        except Exception as e:
            exception_dict[k]=e #extract exception
            test_case_dict.pop(k)
            try_except_avoider(test_case_dict) #recursive function to handle remaining functions

        finally:  #cleanup
            final_dict.update(exception_dict)
            return final_dict #combine exception dict and  final dict

    return try_except_avoider(test_case_dict) 

Run code:

def add(a,b):
    return (a+b)
def sub(a,b):
    return (a-b)
def mul(a,b):
    return (a*b)

case = {"AddFunc":"add(8,8)","SubFunc":"sub(p,5)","MulFunc":"mul(9,6)"}
solution = special_func(case)

Output looks like:

{'AddFunc': 16, 'MulFunc': 54, 'SubFunc': NameError("name 'p' is not defined")}

To convert to variables:

locals().update(solution)

Variables would look like:

AddFunc = 16, MulFunc = 54, SubFunc = NameError("name 'p' is not defined")
Answered By: DeWil

‘continue’ is allowed within an ‘except’ or ‘finally’ only if the try block is in a loop. ‘continue’ will cause the next iteration of the loop to start.

So you can try put your two or more functions in a list and use loop to call your function.

Like this:

funcs = [f,g]
for func in funcs:
    try: func()
    except: continue

For full information you can go to this link

Answered By: LIU ZHIWEN

This can be done with exec() in a custom function, a list of strings, and a for loop.

The function with exec():

def try_it(string):
    try:
        exec(string)
        print(f'Done: {string}')
    except:
        print(f'Error. Could not do: {string}')

More on exec():
exec(object)
This function supports dynamic execution of Python code. object must be either a string or a code object.

Example list of strings and for loop:

do_smth_list = ['do_smth1()', 'do_smth2()', 'do_smth3()'] 

for smth in do_smth_list:
    try_it(smth)
Answered By: wisedesign

This definitely isn’t the cleanest way of doing it, but you can put it in a while loop with a variable set to true, and when it runs the function successfully it sets the variable to false, whereas if it fails it keeps the variable set to true.

x = True
while x == True:
    try:
        do_smth1()
        do_smth2()
        x = False
    except Exception:
        x = True

This way what happens is that the while loop will keep on looping the try except section again and again until it works, in which x is set to false and the loop stops

Also, you can implement a break in the while loop instead of basing it on a variable, for example:

while True:
    try:
        do_smth1()
        do_smth2()
        break
    except Excpetion:
        pass

P.S It is good ettiquete to put a specific exception for the except section, instead of leaving it for any exception. It makes the code cleaner and is more sensible when managing errors especially in bigger projects

Answered By: David Zatica

If do_smth1() worked, then do_smth2() will not be tried.

try:
    x=do_smth1()
except:
    try:
        x=do_smth2()
    except:
        x="Both Failed"

print (x)
Answered By: Adam Safier
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.