How to Serialize an Exception to a JSON-Safe Dict in Python
Convert any Python exception into a JSON-safe dictionary with type, message, and the last few traceback lines for logging.
Python code
20 linesimport json
import traceback
from typing import Any
def exception_to_dict(exc: Exception) -> dict[str, Any]:
"""Convert an exception into a JSON-safe dictionary."""
return {
"type": type(exc).__name__,
"message": str(exc),
"traceback": traceback.format_exc().strip().split("\n")[-3:],
}
if __name__ == "__main__":
try:
value = 10 / 0
except ZeroDivisionError as e:
result = exception_to_dict(e)
print(json.dumps(result, indent=2))
Output
{
"type": "ZeroDivisionError",
"message": "division by zero",
"traceback": [
" value = 10 / 0",
"ZeroDivisionError: division by zero"
]
}
How it works
The exception_to_dict function uses type(exc).__name__ to capture the exception class name and str(exc) for a human-readable message. traceback.format_exc() returns the full formatted traceback of the currently-handled exception, and splitting on newlines lets us keep the last few lines so logs stay compact. Because the result is a plain dict of strings and lists, json.dumps can serialize it without custom encoders. This pattern is useful for structured logging or sending error details to a monitoring service.
Common mistakes
- Calling `traceback.format_exc()` outside an `except` block returns an empty string.
- Using `str(exc)` on exceptions with no message yields an empty string; combine with the type for context.
- Including the full traceback can bloat JSON logs — trim it to a manageable number of lines.
Variations
- Use `exc.__traceback__` with `traceback.extract_tb` for a more structured list of frames instead of raw lines.
- Add a `datetime.utcnow().isoformat()` timestamp key so logs are time-stamped for correlation.
Real-world use cases
- Logging structured error payloads to a JSON-based monitoring service like Datadog or Sentry.
- Serializing exception details to JSON for an API error response so clients can parse and display issues.
- Sending failed job metadata to a message queue for a retry pipeline or dead-letter analysis.
Sponsored
More from Errors & debugging
- Catch RecursionError and Fail Gracefully in Python easy
- Catch ValueError and print friendly message in Python easy
- Collect Multiple Validation Errors in Python Before Raising medium
- Handle ValueError and ZeroDivisionError in Python with try except easy
- How to Add a Correlation ID to Logging Records in Python medium
- How to Assert Preconditions with Descriptive Messages in Python easy
Keep learning
Related tutorials and quizzes for this topic.