Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is "except:" able to catch this error but not "except Exception, e:"?

Tags:

python

fabric

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?

like image 297
Tinker Avatar asked Sep 15 '25 15:09

Tinker


1 Answers

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.

like image 120
user2357112 supports Monica Avatar answered Sep 18 '25 05:09

user2357112 supports Monica