traceback.format_exc() will yield more info if that's what you want.
import traceback
def do_stuff():
raise Exception("test exception")
try:
do_stuff()
except Exception:
print(traceback.format_exc())
This outputs:
Traceback (most recent call last):
File "main.py", line 9, in <module>
do_stuff()
File "main.py", line 5, in do_stuff
raise Exception("test exception")
Exception: test exception
Answer from volting on Stack Overflowtraceback.format_exc() will yield more info if that's what you want.
import traceback
def do_stuff():
raise Exception("test exception")
try:
do_stuff()
except Exception:
print(traceback.format_exc())
This outputs:
Traceback (most recent call last):
File "main.py", line 9, in <module>
do_stuff()
File "main.py", line 5, in do_stuff
raise Exception("test exception")
Exception: test exception
Some other answer have already pointed out the traceback module.
Please notice that with print_exc, in some corner cases, you will not obtain what you would expect. In Python 2.x:
import traceback
try:
raise TypeError("Oups!")
except Exception, err:
try:
raise TypeError("Again !?!")
except:
pass
traceback.print_exc()
...will display the traceback of the last exception:
Traceback (most recent call last):
File "e.py", line 7, in <module>
raise TypeError("Again !?!")
TypeError: Again !?!
If you really need to access the original traceback one solution is to cache the exception infos as returned from exc_info in a local variable and display it using print_exception:
import traceback
import sys
try:
raise TypeError("Oups!")
except Exception, err:
try:
exc_info = sys.exc_info()
# do you usefull stuff here
# (potentially raising an exception)
try:
raise TypeError("Again !?!")
except:
pass
# end of useful stuff
finally:
# Display the *original* exception
traceback.print_exception(*exc_info)
del exc_info
Producing:
Traceback (most recent call last):
File "t.py", line 6, in <module>
raise TypeError("Oups!")
TypeError: Oups!
Few pitfalls with this though:
From the doc of
sys_info:Assigning the traceback return value to a local variable in a function that is handling an exception will cause a circular reference. This will prevent anything referenced by a local variable in the same function or by the traceback from being garbage collected. [...] If you do need the traceback, make sure to delete it after use (best done with a try ... finally statement)
but, from the same doc:
Beginning with Python 2.2, such cycles are automatically reclaimed when garbage collection is enabled and they become unreachable, but it remains more efficient to avoid creating cycles.
On the other hand, by allowing you to access the traceback associated with an exception, Python 3 produce a less surprising result:
import traceback
try:
raise TypeError("Oups!")
except Exception as err:
try:
raise TypeError("Again !?!")
except:
pass
traceback.print_tb(err.__traceback__)
... will display:
File "e3.py", line 4, in <module>
raise TypeError("Oups!")
Print Full Python Traceback Without Halting Program - TestMu AI Community
python - Storing and printing an exception with traceback? - Stack Overflow
Disable printing in unit tests
How do I print a custom error message without Python returning a traceback?
What does it mean by "print an exception" in Python?
Why is printing exceptions crucial?
Videos
Use the traceback module. For Python 3.10 and up, you can just write
for exc in errors:
traceback.print_exception(exc)
On previous versions, traceback.print_exception only supports the old type/value/traceback format, so you'll have to extract type(exc) and exc.__traceback__ yourself:
for exc in errors:
traceback.print_exception(type(exc), exc, exc.__traceback__)
Also, be aware that Python has a very strange way of building tracebacks, where an entry for a stack frame is added to the traceback when an exception propagates into that stack frame, rather than building the traceback all at once when the exception is created or raised.
This means that an exception's traceback stops at the point where it stopped propagating. When your the_method catches an exception, the exception's traceback will stop at the_method.
Exceptions have attributes, just like other objects in Python. You may want to explore the attributes of your exceptions. Consider the following example:
>>> try:
import some_junk_that_doesnt_exist
except Exception as error:
print(dir(error))
['__cause__', '__class__', '__context__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__suppress_context__', '__traceback__', '_not_found', 'args', 'msg', 'name', 'path', 'with_traceback']
This means that for each exception in your list, you can access the exception's attribute. Thus, you can do the following:
for e in err:
print(e.args)
print(e.name)
print(e.msg)
One thing that occurs to me, though, is that the following line shouldn't really append more than one exception to your errors list:
except Exception as e:
errors.append(e)
Someone else will know better than I would, but isn't Exception always going to be one thing here (unless you're capturing multiple specific exceptions)?