How to serialize an Exception
When I try to serialize an exception using json.dump
, I get errors like
TypeError: 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"
}
}
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())
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)))