如何序列化异常

问题描述 投票:0回答:3

当我尝试使用

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"
  }
}
python json python-2.7 exception serialization
3个回答
16
投票

您可以将

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)))

10
投票

异常不能被pickle(默认),你有两个选择:

  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())

0
投票

这是我解决问题的方法,以防这也对其他人有帮助:

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

目标是将任何异常序列化为实际异常:

  • “type”是实际的异常类名称(例如 AttributeError)
  • “描述”是简短的细节(例如“str”属性没有属性“_meta”)
  • “详细信息”是代码、文件、行号、调用堆栈的回溯列表。 最终结果是 UI 可以确定显示多少内容,以便为用户提供一些智能错误消息以捕获并发送给帮助台。

我遵循的规则是始终返回 HTTP 200 并在响应 JSON 中指示是否成功或不允许调用者处理它。

当不处于调试模式时,可以抑制回溯,但其想法是提供足够的信息,以便当用户致电帮助台时,他们得到的不仅仅是“它不起作用”。

© www.soinside.com 2019 - 2024. All rights reserved.