See the traceback module, specifically the format_exc() function. Here.
import traceback
try:
raise ValueError
except ValueError:
tb = traceback.format_exc()
else:
tb = "No error"
finally:
print(tb)
Answer from kindall on Stack OverflowSee the traceback module, specifically the format_exc() function. Here.
import traceback
try:
raise ValueError
except ValueError:
tb = traceback.format_exc()
else:
tb = "No error"
finally:
print(tb)
Let's create a decently complicated stacktrace, in order to demonstrate that we get the full stacktrace:
def raise_error():
raise RuntimeError('something bad happened!')
def do_something_that_might_error():
raise_error()
Logging the full stacktrace
A best practice is to have a logger set up for your module. It will know the name of the module and be able to change levels (among other attributes, such as handlers)
import logging
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)
And we can use this logger to get the error:
try:
do_something_that_might_error()
except Exception as error:
logger.exception(error)
Which logs:
ERROR:__main__:something bad happened!
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "<stdin>", line 2, in do_something_that_might_error
File "<stdin>", line 2, in raise_error
RuntimeError: something bad happened!
And so we get the same output as when we have an error:
>>> do_something_that_might_error()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in do_something_that_might_error
File "<stdin>", line 2, in raise_error
RuntimeError: something bad happened!
Getting just the string
If you really just want the string, use the traceback.format_exc function instead, demonstrating logging the string here:
import traceback
try:
do_something_that_might_error()
except Exception as error:
just_the_string = traceback.format_exc()
logger.debug(just_the_string)
Which logs:
DEBUG:__main__:Traceback (most recent call last):
File "<stdin>", line 2, in <module>
File "<stdin>", line 2, in do_something_that_might_error
File "<stdin>", line 2, in raise_error
RuntimeError: something bad happened!
The correct function for tb.something(e) is
''.join(tb.format_exception(None, e, e.__traceback__))
This approach of this answer is new since Python 3.10. This reusable function writes the exception and traceback into a string buffer, and from there as a string.
import io
import traceback
def get_exception_traceback_str(exc: Exception) -> str:
# Ref: https://stackoverflow.com/a/76584117/
file = io.StringIO()
traceback.print_exception(exc, file=file)
return file.getvalue().rstrip()
Sample usage:
try:
assert False, 'testing assertion'
except Exception as exc:
error = get_exception_traceback_str(exc)
print(error)
Sample output:
Traceback (most recent call last):
File "<input>", line 2, in <module>
AssertionError: testing assertion
Note: To just print the exception and traceback instead, you don't need it in a string, so consider using just traceback.print_exception(exc).