web-dev-qa-db-ja.com

例外をシリアル化する方法

_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"
  }
}
_
9
sds

例外をピクルスにすることはできません(デフォルト)。2つのオプションがあります。

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

以下のように、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)))
1
David Weinberg