3

I have the following file:

from fabric.api import env, execute, run

env.hosts = ['1.2.3.4']

def taskA():
    run('ls')

def main():
  try:
    execute(taskA)
  except:
    print "Exception Caught"

main()

I am able to see "Exception Caught" printed when I run this:

$ python test.py
[1.2.3.4] Executing task 'taskA'
[1.2.3.4] run: ls

Fatal error: Timed out trying to connect to 1.2.3.4 (tried 1 time)

Underlying exception:
    timed out

Aborting.
Exception Caught

However, when I switch it to this:

def main():
  try:
    execute(taskA)
  except Exception, e:
    print "Exception Caught", e

main()

I don't see the exception being caught:

[1.2.3.4] run: ls

Fatal error: Timed out trying to connect to 1.2.3.4 (tried 1 time)

Underlying exception:
    timed out

Aborting.

Is there a reason why I am able to catch the error in the code above and not below?

Tinker
  • 4,165
  • 6
  • 33
  • 72

2 Answers2

7

This exception does not derive from Exception. It looks like a SystemExit, which derives from BaseException directly. except Exception only catches instances of Exception.

If you really want to catch absolutely all exceptions, you can do that with

except BaseException as e:

SystemExit is thrown by sys.exit and a few similar functions to cause an interpreter shutdown (or at least end the thread) while still running __exit__ methods and finally blocks. It can also be thrown manually.

BaseException exists so SystemExit and a few similar exceptions aren't caught by except Exception blocks that usually aren't intended to handle them. It's similar to Java's Throwable. Personally, I wish plain except: blocks didn't catch BaseException; it defeats some of the purpose of having BaseException in the first place.

user2357112
  • 260,549
  • 28
  • 431
  • 505
5

When you use except Exception, e, it

doesn't catch BaseException or the system-exiting exceptions SystemExit, KeyboardInterrupt and GeneratorExit

where as except catches all exception types. See Difference between except: and except Exception as e: in Python.

As a result you see "Exception Caught" when using except, however not when using except Exception, e

From the fab docs

If a Python exception is thrown, fab aborts with an exit status of 1.

TheoretiCAL
  • 19,461
  • 8
  • 43
  • 65