捕获异常变量详细信息-cgitb模块

捕获异常变量详细信息-cgitb模块

1.概述

当我们捕获异常时正常输出的异常上下文信息只有调用的模块、类、方法、如果想查看异常时变量值是看不到的。我们只有debug程序才能找到异常原因。
使用cgitb模块能够输出发生异常时所有信息,包括程序执行每个步骤变量信息,方便我们从异常信息中分析出原因。省去了debug过程,提高排查问题的效率。

2.cgitb模块使用

2.1.开启详细异常信息追踪

1.默认Python输出的异常信息

Python 的默认异常处理器会把错误发生位置的保准错误输出流打印出来。基本上也包含了足够的信息让我们理解为什么会引起错误以及随后修复它。

def func2(a, divisor):
    return a / divisor

def func1(a, b):
    c = b - 5
    return func2(a, c)

func1(1, 5)

运行之后会有一个不容易发现错误出现原因异常信息,这里只能看到异常原因是division by zero。但是我们想知道它是如何发生的,就分析不到了因为我们看不到程序每一步运行时divisor变量的值,需要我们在程序中debug查找出错原因。

Traceback (most recent call last):
  File "cgitb_basic_traceback.py", line 18, in <module>
    func1(1, 5)
  File "cgitb_basic_traceback.py", line 16, in func1
    return func2(a, c)
  File "cgitb_basic_traceback.py", line 11, in func2
    return a / divisor
ZeroDivisionError: division by zero

2.开启详细异常信息

如果某函数或方法包含大量的注释,空格或其他无关代码导致它的上下文很长。默认的 5 行上下文可能就不够提供足够指示。所以显示在屏幕上之后很可能没有足够的上下文来让我们理解错误的发生。我们可以给 cgitb 指定更多的上下文值来解决这个问题。给 enable() 的 context 指定一个整数即可控制显示出来的上下文代码量。

我们设置为 12 之后就发现 self.a 和 self.b 也牵扯其中。

import cgitb
cgitb.enable(format='text', context=12)

class BrokenClass:
    """This class has an error.
    """

    def __init__(self, a, b):
        """Be careful passing arguments in here.
        """
        self.a = a
        self.b = b
        self.c = self.a * self.b
        # Really
        # long
        # comment
        # goes
        # here.
        self.d = self.a / self.b
        return

o = BrokenClass(1, 0)

运行结果

python3 cgitb_with_classes.py

ZeroDivisionError
Python 3.6.4: .../bin/python3
Sun Mar 18 16:20:19 2018

A problem occurred in a Python script.  Here is the sequence of
function calls leading up to the error, in the order they
occurred.

 .../cgitb_with_classes.py in <module>()
   21         self.a = a
   22         self.b = b
   23         self.c = self.a * self.b
   24         # Really
   25         # long
   26         # comment
   27         # goes
   28         # here.
   29         self.d = self.a / self.b
   30         return
   31
   32 o = BrokenClass(1, 0)
o undefined
BrokenClass = <class '__main__.BrokenClass'>

 .../cgitb_with_classes.py in
 __init__(self=<__main__.BrokenClass object>, a=1, b=0)
   21         self.a = a
   22         self.b = b
   23         self.c = self.a * self.b
   24         # Really
   25         # long
   26         # comment
   27         # goes
   28         # here.
   29         self.d = self.a / self.b
   30         return
   31
   32 o = BrokenClass(1, 0)
self = <__main__.BrokenClass object>
self.d undefined
self.a = 1
self.b = 0
ZeroDivisionError: division by zero
    __cause__ = None
    __class__ = <class 'ZeroDivisionError'>
    __context__ = None
    __delattr__ = <method-wrapper '__delattr__' of
    ZeroDivisionError object>
    __dict__ = {}
    __dir__ = <built-in method __dir__ of ZeroDivisionError
    object>
    __doc__ = 'Second argument to a division or modulo operation
    was zero.'
    __eq__ = <method-wrapper '__eq__' of ZeroDivisionError
    object>
    __format__ = <built-in method __format__ of
    ZeroDivisionError object>
    __ge__ = <method-wrapper '__ge__' of ZeroDivisionError
    object>
    __getattribute__ = <method-wrapper '__getattribute__' of
    ZeroDivisionError object>
    __gt__ = <method-wrapper '__gt__' of ZeroDivisionError
    object>
    __hash__ = <method-wrapper '__hash__' of ZeroDivisionError
    object>
    __init__ = <method-wrapper '__init__' of ZeroDivisionError
    object>
    __init_subclass__ = <built-in method __init_subclass__ of
    type object>
    __le__ = <method-wrapper '__le__' of ZeroDivisionError
    object>
    __lt__ = <method-wrapper '__lt__' of ZeroDivisionError
    object>
    __ne__ = <method-wrapper '__ne__' of ZeroDivisionError
    object>
    __new__ = <built-in method __new__ of type object>
    __reduce__ = <built-in method __reduce__ of
    ZeroDivisionError object>
    __reduce_ex__ = <built-in method __reduce_ex__ of
    ZeroDivisionError object>
    __repr__ = <method-wrapper '__repr__' of ZeroDivisionError
    object>
    __setattr__ = <method-wrapper '__setattr__' of
    ZeroDivisionError object>
    __setstate__ = <built-in method __setstate__ of
    ZeroDivisionError object>
    __sizeof__ = <built-in method __sizeof__ of
    ZeroDivisionError object>
    __str__ = <method-wrapper '__str__' of ZeroDivisionError
    object>
    __subclasshook__ = <built-in method __subclasshook__ of type
    object>
    __suppress_context__ = False
    __traceback__ = <traceback object>
    args = ('division by zero',)
    with_traceback = <built-in method with_traceback of
    ZeroDivisionError object>

The above is a description of an error in a Python program.
Here is
the original traceback:

Traceback (most recent call last):
  File "cgitb_with_classes.py", line 32, in <module>
    o = BrokenClass(1, 0)
  File "cgitb_with_classes.py", line 29, in __init__
    self.d = self.a / self.b
ZeroDivisionError: division by zero

2.2.记录 Traceback

大多数场景中,打印出标准错误的追踪详情是很好的解决方式。不过在生产系统中,把它记录下来更加棒一些。enable() 函数有一个 logdir 参数,可以指定错误的记录目录。指定了目录后,每条异常都会被记录到给定的目录中。

import os

LOGDIR = os.path.join(os.path.dirname(__file__), 'LOGS')

if not os.path.exists(LOGDIR):
    os.makedirs(LOGDIR)

cgitb.enable(
    logdir=LOGDIR,
    display=False,
    format='text',
)

def func(a, divisor):
    return a / divisor

func(1, 0)python

运行结果

<p>A problem occurred in a Python script.
.../LOGS/tmpq7icvee3.txt contains the description of this error.

$ ls LOGS

tmpq7icvee3.txt

$ cat LOGS/*.txt

ZeroDivisionError
Python 3.6.4: .../bin/python3
Sun Mar 18 16:20:19 2018

A problem occurred in a Python script.  Here is the sequence of
function calls leading up to the error, in the order they
occurred.

 .../cgitb_log_exception.py in <module>()
   24
   25 def func(a, divisor):
   26     return a / divisor
   27
   28 func(1, 0)
func = <function func>

 .../cgitb_log_exception.py in func(a=1, divisor=0)
   24
   25 def func(a, divisor):
   26     return a / divisor
   27
   28 func(1, 0)
a = 1
divisor = 0
ZeroDivisionError: division by zero
    __cause__ = None
    __class__ = <class 'ZeroDivisionError'>
    __context__ = None
    __delattr__ = <method-wrapper '__delattr__' of
    ZeroDivisionError object>
    __dict__ = {}
    __dir__ = <built-in method __dir__ of ZeroDivisionError
    object>
    __doc__ = 'Second argument to a division or modulo operation
    was zero.'
    __eq__ = <method-wrapper '__eq__' of ZeroDivisionError
    object>
    __format__ = <built-in method __format__ of
    ZeroDivisionError object>
    __ge__ = <method-wrapper '__ge__' of ZeroDivisionError
    object>
    __getattribute__ = <method-wrapper '__getattribute__' of
    ZeroDivisionError object>
    __gt__ = <method-wrapper '__gt__' of ZeroDivisionError
    object>
    __hash__ = <method-wrapper '__hash__' of ZeroDivisionError
    object>
    __init__ = <method-wrapper '__init__' of ZeroDivisionError
    object>
    __init_subclass__ = <built-in method __init_subclass__ of
    type object>
    __le__ = <method-wrapper '__le__' of ZeroDivisionError
    object>
    __lt__ = <method-wrapper '__lt__' of ZeroDivisionError
    object>
    __ne__ = <method-wrapper '__ne__' of ZeroDivisionError
    object>
    __new__ = <built-in method __new__ of type object>
    __reduce__ = <built-in method __reduce__ of
    ZeroDivisionError object>
    __reduce_ex__ = <built-in method __reduce_ex__ of
    ZeroDivisionError object>
    __repr__ = <method-wrapper '__repr__' of ZeroDivisionError
    object>
    __setattr__ = <method-wrapper '__setattr__' of
    ZeroDivisionError object>
    __setstate__ = <built-in method __setstate__ of
    ZeroDivisionError object>
    __sizeof__ = <built-in method __sizeof__ of
    ZeroDivisionError object>
    __str__ = <method-wrapper '__str__' of ZeroDivisionError
    object>
    __subclasshook__ = <built-in method __subclasshook__ of type
    object>
    __suppress_context__ = False
    __traceback__ = <traceback object>
    args = ('division by zero',)
    with_traceback = <built-in method with_traceback of
    ZeroDivisionError object>

The above is a description of an error in a Python program.
Here is
the original traceback:

Traceback (most recent call last):
  File "cgitb_log_exception.py", line 28, in <module>
    func(1, 0)
  File "cgitb_log_exception.py", line 26, in func
    return a / divisor
ZeroDivisionError: division by zero

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值