How to serialize an Exception
Solution 1
Exceptions can not be pickled (by default), you have two options:
Use Python's built in format_exc() and serialize the formatted string.
Use
tblib
With the latter, you can pass wrapped exceptions and also reraise them later.
import tblib.pickling_support
tblib.pickling_support.install()
import pickle, sys
def inner_0():
raise Exception('fail')
def inner_1():
inner_0()
def inner_2():
inner_1()
try:
inner_2()
except:
s1 = pickle.dumps(sys.exc_info())
Solution 2
You can use exc_info
with traceback
as below:
import traceback
import sys
try:
raise KeyError('aaa!!!')
except Exception as e:
exc_info = sys.exc_info()
print(''.join(traceback.format_exception(*exc_info)))
Comments
-
sds almost 2 years
When I try to serialize an exception using
json.dump
, I get errors likeTypeError: IOError('socket error', error(61, 'Connection refused')) is not JSON serializable
and
TypeError: error(61, 'Connection refused') is not JSON serializable
The
__dict__
field of exceptions is{}
(this is why How to make a class JSON serializable does not help me: the answers there assume that__dict__
contains all the necessary information, they also assume that I have control over the class to be serialized).Is there something more intelligent that saving
str(exn)
?I would prefer a human-readable text representation (not
pickle
).PS. Here is what I came up with:
def exception_as_dict(ex): return dict(type=ex.__class__.__name__, errno=ex.errno, message=ex.message, strerror=exception_as_dict(ex.strerror) if isinstance(ex.strerror,Exception) else ex.strerror) json.dumps(exception_as_dict(err),indent=2) { "errno": "socket error", "type": "IOError", "strerror": { "errno": 61, "type": "error", "strerror": "Connection refused" } }