如何序列化异常

时间:2017-07-21 14:44:18

标签: python json python-2.7 exception serialization

当我尝试使用TypeError: IOError('socket error', error(61, 'Connection refused')) is not JSON serializable 序列化异常时,我会收到类似

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

__dict__

{}例外字段为__dict__(这就是How to make a class JSON serializable无法帮助我的原因:那里的答案假设str(exn)包含所有必要的信息,他们也是假设我可以控制要序列化的类。

是否有更智能的保存pickle

我更喜欢人类可读的文字表示(不是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" } } )。

PS。以下是我提出的建议:

id|parentId|alias|value|datepoint
181565 |1|frequency6   |0    |2017-07-21 16:45:22.763
181566 |1|tag          |1    |2017-07-21 16:45:22.763
181567 |1|ord          |45688|2017-07-21 16:45:22.763
181568 |1|target_status|-1   |2017-07-21 16:45:22.763
1032193|1|frequency6   |0    |2017-07-21 17:15:04.833
1032194|1|tag          |1    |2017-07-21 17:15:04.833
1032195|1|ord          |45688|2017-07-21 17:15:04.833
1032196|1|target_status|-1   |2017-07-21 17:15:04.833
873321 |2|frequency6   |0    |2017-07-21 17:14:00.443
873322 |2|tag          |1    |2017-07-21 17:14:00.443
873323 |2|ord          |5726 |2017-07-21 17:14:00.443
873324 |2|target_status|-1   |2017-07-21 17:14:00.443
22693  |2|frequency6   |0    |2017-07-21 16:44:13.290
22694  |2|tag          |1    |2017-07-21 16:44:13.290
22695  |2|ord          |5726 |2017-07-21 16:44:13.290
22696  |2|target_status|-1   |2017-07-21 16:44:13.290
75625  |3|frequency6   |0    |2017-07-21 16:44:31.037

2 个答案:

答案 0 :(得分:4)

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

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

  2. 使用tblib

  3. 使用后者,您可以传递包装的异常,并在以后重新加载它们。

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

答案 1 :(得分:1)

您可以将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)))