当我尝试使用
json.dump
序列化异常时,我收到如下错误
TypeError: IOError('socket error', error(61, 'Connection refused')) is not JSON serializable
和
TypeError: error(61, 'Connection refused') is not JSON serializable
异常的
__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"
}
}
您可以将
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)))
异常不能被pickle(默认),你有两个选择:
使用Python内置的format_exc()并序列化格式化字符串。
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())
这是我解决问题的方法,以防这也对其他人有帮助:
except Exception as error:
exc_info = sys.exc_info()
sExceptionInfo = ''.join(traceback.format_exception(*exc_info))
exc_type, exc_value, exc_context = sys.exc_info()
rHttpResponse = JsonResponse(
{
"status": "error",
"type": exc_type.__name__,
"description": str(exc_value),
"details": sExceptionInfo
}
)
return rHttpResponse
目标是将任何异常序列化为实际异常:
我遵循的规则是始终返回 HTTP 200 并在响应 JSON 中指示是否成功或不允许调用者处理它。
当不处于调试模式时,可以抑制回溯,但其想法是提供足够的信息,以便当用户致电帮助台时,他们得到的不仅仅是“它不起作用”。