现在的位置: 首页 > 综合 > 正文

如何把异常信息格式化为字符串

2014年02月28日 ⁄ 综合 ⁄ 共 1852字 ⁄ 字号 评论关闭
         如何把异常信息格式化为字符串

             Horin|贺勤
        Email: horin153@msn.com
        Blog: http://blog.csdn.net/horin153/

    Python 的 traceback.py 模块在调试中非常有用;但其默认的输出方式是 sys.stderr,导致在 realse 版本中(屏蔽了标准输出)无法有效捕获程序异常。如果把 traceback 的输出定向到我们能控制的 buffer 中,比如字符串,我们就能把捕获到的异常信息进行希望的后期处理,比如记入日志文件中。

    下面的代码段就实现了这个功能:

#--------------- code begin --------------

# -*- coding: utf-8 -*-

import traceback

_title_tag = "[Traceback]/n"
class CStringBuf:
    def __init__(self, title_tag="[Traceback]/n"):
        self._buf = title_tag

    def write(self, _str):
        self._buf += _str

    def read(self):
        return self._buf

def handle_traceback(ex, mode=0x2, limit=None, title_tag=None):
    """up to 'limit' stack trace entries to a string.
    """
    # mode:bit_1:print_stack,bit_2:print_exc;0xf:print all.
    # if title_tag is None, use _titlt_tag.
    if title_tag is None:
        title_tag = _title_tag
    _file = CStringBuf(title_tag)

    if mode & 0x1:
        traceback.print_stack(None, limit, _file)
    if mode & 0x2:
        traceback.print_exc(limit, _file)
    if __debug__:
        print '!!!!! handle_traceback begin !!!!!'
        print _file.read()
        print '!!!!! handle_traceback end !!!!!'
        raise Exception, ex
    else:
        return _file.read()

#---test---
def crash():
        _i = 5/0

def test():
    try:
        crash()
    except Exception, ex:
        handle_traceback(ex)

if __name__=="__main__":
    test()

#--------------- code end ----------------

    测试结果如下:
##---output---
#!!!!! handle_traceback begin !!!!!
#[Traceback]
#Traceback (most recent call last):
#  File "F:/python/str_traceback.py", line 44, in test
#    crash()
#  File "F:/python/str_traceback.py", line 40, in crash
#    _i = 5/0
#ZeroDivisionError: integer division or modulo by zero
#
#!!!!! handle_traceback end !!!!!

    实现原理是:用 CStringBuf 代替 traceback 中的 file,也就把捕获到的异常信息定向到了字符串中。
    handle_traceback() 的参数如下:
-- ex: 捕获到的异常,以便在 debug 时重新抛出;
-- mode: 处理模式,第一位为1时打印当前调用栈,第二位为1时打印异常信息;
-- limit: 打印调用栈的最大层次数;
-- title_tag: 在异常信息前打印的标签字符串。
    使用很简单,就像 test() 函数一样:try 捕获异常,再用 handle_traceback 处理。

抱歉!评论已关闭.