Explain Codes LogoExplain Codes Logo

Get exception description and stack trace which caused an exception, all as a string

python
exception-handling
logging
traceback
Alex KataevbyAlex KataevΒ·Feb 8, 2025
⚑TLDR

To capture an exception's message and corresponding stack trace as a string, you can leverage the traceback module in Python. The function traceback.format_exc() is your go-to choice for this use-case.

Here's a straightforward example:

import traceback try: # Your code that may raise an exception β€” Murphy's Law πŸ˜‰ pass except: print(traceback.format_exc())

Digging deeper: Advanced Usage

Let's dive into some more in-depth and elevated aspects of handling and formatting exceptions.

1. The power of TracebackException: Flexible formatting

From Python 3.5 onwards, you can use traceback.TracebackException to obtain an object representation of an exception. Then, this can be transformed into a customizable string:

import traceback try: # Your code with a rebel streak pass except Exception as e: tb_exception = traceback.TracebackException.from_exception(e) fmt_exception = ''.join(tb_exception.format()) # formatting our rebellious exception print(fmt_exception)

This method gives you granular control over the exception information, which comes in handy when you need to filter or rearrange traceback elements.

2. The art of logging: For error proofing

If your application requires rigorous logging, bring in Python's logging module to catch and log exceptions on the fly:

import logging import traceback logging.basicConfig(level=logging.ERROR) # Level up, exception – game on πŸ‘Ύ logger = logging.getLogger(__name__) try: # Your code with a plot twist pass except: logger.exception("An error occurred:") # Plot twist handled 🎬

logger.exception automatically logs the traceback into the log entries, making troubleshooting a breeze.

3. Sneak peek with __traceback__: Accessing stack trace directly

You can directly access the stack trace of an exception using its __traceback__ attribute:

try: # Code block attempting a risky move pass except Exception as e: trace_str = ''.join(traceback.format_tb(e.__traceback__)) print(trace_str) # Yes, we print the sneaky stack trace πŸ•΅οΈβ€β™€οΈ

This is extremely useful when you need to inspect the stack trace before converting it to a string.

4. Expressive logging: Verbose outputs for a better lookout

Verbose outputs are like driving a convertible on a highway – it could be a joy ride for a large-scale system, but a bit overwhelming for a small sprinter. To see beyond just the exception message and the immediate stack trace, you can adjust the log level to see more details:

import logging logging.basicConfig(level=logging.DEBUG) # DEBUG - the Sherlock Holmes of logging πŸ•΅οΈβ€β™‚οΈ

5. The perceptual scope of sys.exc_info()

In some complex exception handling scenarios, you might be outside the except clause or a different execution frame listening for exceptions. In such situations, sys.exc_info() comes to the rescue:

import sys import traceback try: # Code that likes to live on the edge pass except: exc_type, exc_value, exc_traceback = sys.exc_info() # Detect and dissect the exception print(''.join(traceback.format_exception(exc_type, exc_value, exc_traceback)))

sys.exc_info() returns a tuple with the exception type, value, and traceback.

6. Custom error reporting format

If you need to report the error externally, for instance, to a tracking system, you might need a specific format implemented:

import traceback try: # The code that could cause chaos pass except Exception as e: error_report = { "type": str(type(e).__name__), # Type of chaos "message": str(e), # The chaos itself "trace": traceback.format_exc(), # Tracing the chaos } send_error_report(error_report) # Sending the chaos report

This enables you to create the dictionary of error details in a format that your reporting system prefers.