如何序列化异常

sds*_*sds 6 python serialization json exception python-2.7

当我尝试使用序列化异常时json.dump,出现类似

TypeError: IOError('socket error', error(61, 'Connection refused')) is not JSON serializable
Run Code Online (Sandbox Code Playgroud)

TypeError: error(61, 'Connection refused') is not JSON serializable
Run Code Online (Sandbox Code Playgroud)

__dict__异常的字段是{}(这就是为什么如何使JSON可序列化的类对我没有帮助:那里的答案假定__dict__包含所有必要的信息,并且还假定我可以控制要序列化的类)。

有比保存更聪明的东西str(exn)吗?

我希望使用人类可读的文本表示形式(不是pickle)。

PS。这是我想出的:

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"
  }
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*erg 6

您可以使用exc_info具有traceback如下:

import traceback
import sys
try:
    raise KeyError('aaa!!!')
except Exception as e:
    exc_info = sys.exc_info()
    print(''.join(traceback.format_exception(*exc_info)))
Run Code Online (Sandbox Code Playgroud)


kni*_*nap 5

无法腌制例外(默认情况下),您有两个选择:

  1. 使用Python内置的format_exc()并序列化格式化的字符串。

  2. 使用 tblib

使用后者,您可以传递包装的异常,并在以后重新引发它们。

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())
Run Code Online (Sandbox Code Playgroud)