I have a function called by the main program:
try:
someFunction()
except:
print \"exception happened!\"
but in the middle of the ex
Most answers point to except (…) as (…):
syntax (rightly so) but at the same time nobody wants to talk about an elephant in the room, where the elephant is sys.exc_info()
function.
From the documentation of sys module (emphasis mine):
This function returns a tuple of three values that give information about the exception that is currently being handled.
(…)
If no exception is being handled anywhere on the stack, a tuple containing three None values is returned. Otherwise, the values returned are (type, value, traceback). Their meaning is: type gets the type of the exception being handled (a subclass of BaseException); value gets the exception instance (an instance of the exception type); traceback gets a traceback object (see the Reference Manual) which encapsulates the call stack at the point where the exception originally occurred.
I think the sys.exc_info()
could be treated as the most direct answer to the original question of How do I know what type of exception occurred?
The actual exception can be captured in the following way:
try:
i = 1/0
except Exception as e:
print e
You can learn more about exceptions from The Python Tutorial.
Get the name of the class that exception object belongs:
e.__class__.__name__
and using print_exc() function will also print stack trace which is essential info for any error message.
Like this:
from traceback import print_exc
class CustomException(Exception): pass
try:
raise CustomException("hi")
except Exception, e:
print 'type is:', e.__class__.__name__
print_exc()
# print "exception happened!"
You will get output like this:
type is: CustomException
Traceback (most recent call last):
File "exc.py", line 7, in <module>
raise CustomException("hi")
CustomException: hi
And after print and analysis, the code can decide not to handle exception and just execute raise
:
from traceback import print_exc
class CustomException(Exception): pass
def calculate():
raise CustomException("hi")
try:
calculate()
except Exception, e:
if e.__class__ == CustomException:
print 'special case of', e.__class__.__name__, 'not interfering'
raise
print "handling exception"
Output:
special case of CustomException not interfering
And interpreter prints exception:
Traceback (most recent call last):
File "test.py", line 9, in <module>
calculate()
File "test.py", line 6, in calculate
raise CustomException("hi")
__main__.CustomException: hi
After raise
original exception continues to propagate further up the call stack. (Beware of possible pitfall) If you raise new exception it caries new (shorter) stack trace.
from traceback import print_exc
class CustomException(Exception): pass
def calculate():
raise CustomException("hi")
try:
calculate()
except Exception, e:
if e.__class__ == CustomException:
print 'special case of', e.__class__.__name__, 'not interfering'
#raise CustomException(e.message)
raise e
print "handling exception"
Output:
special case of CustomException not interfering
Traceback (most recent call last):
File "test.py", line 13, in <module>
raise CustomException(e.message)
__main__.CustomException: hi
Notice how traceback does not include calculate()
function from line 9
which is the origin of original exception e
.