use str
try:
some_method()
except Exception as e:
s = str(e)
Also, most exception classes will have an args attribute. Often, args[0] will be an error message.
It should be noted that just using str will return an empty string if there's no error message whereas using repr as pyfunc recommends will at least display the class of the exception. My take is that if you're printing it out, it's for an end user that doesn't care what the class is and just wants an error message.
It really depends on the class of exception that you are dealing with and how it is instantiated. Did you have something in particular in mind?
Answer from aaronasterling on Stack OverflowVideos
use str
try:
some_method()
except Exception as e:
s = str(e)
Also, most exception classes will have an args attribute. Often, args[0] will be an error message.
It should be noted that just using str will return an empty string if there's no error message whereas using repr as pyfunc recommends will at least display the class of the exception. My take is that if you're printing it out, it's for an end user that doesn't care what the class is and just wants an error message.
It really depends on the class of exception that you are dealing with and how it is instantiated. Did you have something in particular in mind?
Use repr() and The difference between using repr and str
Using repr:
>>> try:
... print(x)
... except Exception as e:
... print(repr(e))
...
NameError("name 'x' is not defined")
Using str:
>>> try:
... print(x)
... except Exception as e:
... print(str(e))
...
name 'x' is not defined
import sys, os
try:
raise NotImplementedError("No error")
except Exception as e:
exc_type, exc_obj, exc_tb = sys.exc_info()
fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
print(exc_type, fname, exc_tb.tb_lineno)
Simplest form that worked for me.
import traceback
try:
print(4/0)
except ZeroDivisionError:
print(traceback.format_exc())
Output
Traceback (most recent call last):
File "/path/to/file.py", line 51, in <module>
print(4/0)
ZeroDivisionError: division by zero
Process finished with exit code 0
If you look at the documentation for the built-in errors, you'll see that most Exception classes assign their first argument as a message attribute. Not all of them do though.
Notably,EnvironmentError (with subclasses IOError and OSError) has a first argument of errno, second of strerror. There is no message... strerror is roughly analogous to what would normally be a message.
More generally, subclasses of Exception can do whatever they want. They may or may not have a message attribute. Future built-in Exceptions may not have a message attribute. Any Exception subclass imported from third-party libraries or user code may not have a message attribute.
I think the proper way of handling this is to identify the specific Exception subclasses you want to catch, and then catch only those instead of everything with an except Exception, then utilize whatever attributes that specific subclass defines however you want.
If you must print something, I think that printing the caught Exception itself is most likely to do what you want, whether it has a message attribute or not.
You could also check for the message attribute if you wanted, like this, but I wouldn't really suggest it as it just seems messy:
try:
pass
except Exception as e:
# Just print(e) is cleaner and more likely what you want,
# but if you insist on printing message specifically whenever possible...
if hasattr(e, 'message'):
print(e.message)
else:
print(e)
To improve on the answer provided by @artofwarfare, here is what I consider a neater way to check for the message attribute and print it or print the Exception object as a fallback.
try:
pass
except Exception as e:
print getattr(e, 'message', repr(e))
The call to repr is optional, but I find it necessary in some use cases.
Update #1:
Following the comment by @MadPhysicist, here's a proof of why the call to repr might be necessary. Try running the following code in your interpreter:
try:
raise Exception
except Exception as e:
print(getattr(e, 'message', repr(e)))
print(getattr(e, 'message', str(e)))
The repr(e) line will print Exception() and the str(e) line will print an empty string.
Update #2:
Here is a demo with specifics for Python 2.7 and 3.5: https://gist.github.com/takwas/3b7a6edddef783f2abddffda1439f533
Here are a few different ways to get the name of the class of the exception:
type(exception).__name__exception.__class__.__name__exception.__class__.__qualname__
e.g.,
try:
foo = bar
except Exception as exception:
assert type(exception).__name__ == 'NameError'
assert exception.__class__.__name__ == 'NameError'
assert exception.__class__.__qualname__ == 'NameError'
If you want the fully qualified class name (e.g. sqlalchemy.exc.IntegrityError instead of just IntegrityError), you can use the function below, which I took from MB's awesome answer to another question (I just renamed some variables to suit my tastes):
def get_full_class_name(obj):
module = obj.__class__.__module__
if module is None or module == str.__class__.__module__:
return obj.__class__.__name__
return module + '.' + obj.__class__.__name__
Example:
try:
# <do something with sqlalchemy that angers the database>
except sqlalchemy.exc.SQLAlchemyError as e:
print(get_full_class_name(e))
# sqlalchemy.exc.IntegrityError