1

Suppose the following code:

try:
    code_a
    code_b
    code_c
except:
    pass

If an error occurs in code_b, then it will be caught by the except and only code_a will have run. Is there a way to ensure code_c runs as well?

I imagine:

try: 
    code_a
except: 
    pass
try: 
    code_b
except: 
    pass
try: 
    code_c
except: 
    pass

is not the right way to go about it.

  • Have you tried it yourself? If not what have you tried? – AverageJoe9000 Jul 01 '20 at 06:24
  • 1
    I think your only bet is to use multiple try statements as if any error is raised you will automatically go to the exception block. Maybe include error handling inside of each function of a, b, and c and determine the state based on the returned value, return -1 if error is raised and 1 other wise and compare all three values. I don't think you're looking for the finally block as it's not going to handle any errors raised, it's just calling a function regardless if exception is raised or not. I hope that helped! – Marsilinou Zaky Jul 01 '20 at 07:12
  • 1
    Also another way of doing it but NOT a good practice is to use eval, so have a function that take cmd as argument and the body of the function is basically try eval(cmd) except Exception pass, and have all your commands in a list and loop through them, this method can't be applied to all cases tho depends on ur program – Marsilinou Zaky Jul 01 '20 at 07:16
  • Does `finally` do what you want? – Karl Knechtel Jul 01 '20 at 07:37
  • also check out the `with` statement in Python (https://stackoverflow.com/a/3012565/2480947). It's often easier than using a `try` block – Nic Jul 02 '20 at 01:01
  • @MarsilinouZaky I like your second idea! Defining a function with `eval()` in a try-except statement seems like a succinct way around this problem (though I think `eval()` can be nebulous at times.) – Randy Sterbentz Jul 02 '20 at 06:14

2 Answers2

5

The short answer to your title question is No. The rest of the try: block will not execute after an exception.

As you note, you can put code_a, code_b and code_c in their own try: blocks and handle errors separately.

You asked if code_c could run even if code_b raised an exception.

Option 1

Put code_c outside the try: block entirely:

try:
    code_a
    code_b
except:
    pass
code_c

But take care. code_c won't definitely execute. it depends what's in the except: block. Consider the following example:

try:
    code_a
    code_b
except:
    return False
code_c
return True

If code_a or code_b raise an exception, code_c will not execute.

Option 2

Use a finally: block:

try:
    code_a
    code_b
except:
    return False
finally:
    code_c
return True

If code_c is in a finally: block it is guaranteed to execute whether or not there is an exception.

If there is no exception, code_c executes after code_a and code_b.

If there is an exception, return False will work as expected BUT code_c will squeeze in and execute just before the function returns. This is because it is guaranteed to execute.

Complete Example

def ham():
    print('Ham please')


def eggs():
    print('Eggs please')
    raise NoEggsException


class NoEggsException(Exception):
    pass


def spam():
    print('Spam Spam Spam Spam Spam!')


def order():
    try:
        ham()
        eggs()
    except NoEggsException:
        print('    ...no eggs :(')
        return False
    finally:
        spam()
    return True


if __name__ == '__main__':
    order_result = order()
    print(f'Order complete: {order_result}')

When run as written, eggs() raises an exception. The result is as follows:

Ham please
Eggs please
    ...no eggs :(
Spam Spam Spam Spam Spam!
Order complete: False

Note that spam() (in the finally: block) is executed even though there is a return False in the except: block.

Here is what happens when raise NoEggsException is commented out or removed:

Ham please
Eggs please
Spam Spam Spam Spam Spam!
Order complete: True

Note that you get spam (and more spam) in your order either way.

Nic
  • 1,518
  • 12
  • 26
0

You can use "finally":

try:
    print(1)
    print(some nonexistent variable)
except:
    pass
finally:
    print(3)

This will print "1" and "3"

BossaNova
  • 1,509
  • 1
  • 13
  • 17
  • I don't think that is the exact use of `finally`. Maybe you can execute it outside `try` block. – Austin Jul 01 '20 at 06:29
  • 1
    I think this is not what he asked. He is asking to run code c, d, e etc after having exception in code b. Finally is used like closing files etc. – Imran Jul 01 '20 at 06:30