如何序列化异常

Posted

技术标签:

【中文标题】如何序列化异常【英文标题】:How to serialize an Exception 【发布时间】:2017-12-27 16:13:28 【问题描述】:

当我尝试使用 json.dump 序列化异常时,我收到类似的错误

TypeError: IOError('socket error', error(61, 'Connection refused')) is not JSON serializable

TypeError: error(61, 'Connection refused') is not JSON serializable

__dict__ 异常字段是(这就是为什么How to make a class JSON serializable 对我没有帮助:那里的答案假设__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"
  

【问题讨论】:

您可以捕获异常对象并腌制它吗?您可以将腌制数据作为 JSON 对象中的二进制有效负载传递。 @cᴏʟᴅsᴘᴇᴇᴅ:我更喜欢人类可读的文本表示。您的评论表明答案是否定的。谢谢。 你没有说清楚。似乎您想要某种远程通信异常的方式。无论如何,您必须寻找一些第 3 方库,或者编写您自己的自定义解析器来解构或构造与 JSON 之间的对象。 How to make a class JSON serializable的可能重复 @Leon: 不是真正的骗子:__dict__Exception 中毫无用处。 【参考方案1】:

异常不能被腌制(默认),你有两种选择:

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

【讨论】:

【参考方案2】:

您可以将exc_infotraceback 一起使用,如下所示:

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

【讨论】:

【参考方案3】:

几天后我会回答这个问题;为了正确处理异常并避免 JSON 序列化错误,您可以在处理异常时将代码包装在 try 块中,如下所示。

    try:

    # your logic here

    except Exception as e:
        return "ERROR" : f"e"

我们在 return 语句中返回一个 Python 字典,但为了避免错误,我们将错误消息包装在一个 fstring 中,如图所示。

【讨论】:

以上是关于如何序列化异常的主要内容,如果未能解决你的问题,请参考以下文章

缺少属性时如何强制 System.Text.Json 序列化程序抛出异常?

Spring Integration and AMQP:如何优雅地处理反序列化异常?

在反序列化过程中出现下一个异常:“源数据中的无效字段:0”。如何找出源代码中的原因/错误位置?

异常,返回,可序列化,

套接字,接收序列化异常

如何在 Spring 中捕获大量 Jackson 异常?