python:raise(“customException”) - 为什么没有堆栈跟踪?

时间:2014-01-28 19:01:15

标签: python custom-exceptions

在python(v2.7.3)中使用自定义异常:调用getSub()时不要获得堆栈跟踪,而getSub(True)调用一个,不同之处在于它是通过额外的尝试引起的......除了我想避免(+感觉不必要),为什么/如何避免?

import sys, traceback

class customException(Exception):
    def __init__(self, *args):
        super(customException,self).__init__(*args)
        print "Stack trace within exception", traceback.extract_tb(sys.exc_info()[2])
        errTxt = [a for a in args]
        print "error text", errTxt

def getFn():
    try:
        getSub()
    except customException as e:
        print "customException was raised"
    try:
        getSub(True)
    except customException as e:
        print "customException2 was raised"

def getSub(flag=False):
    if flag:
        try:
            1/0
        except:
            raise customException('test')
    else:
        raise customException('test')

getFn()

输出:

Stack trace within exception []
error text ['test']
customException was raised
Stack trace within exception [('./test3.py', 25, 'getSub', '1/0')]
error text ['test']
customException2 was raised

要把上面的内容放在上下文中,我在下面的行中有代码(伪),直到我将代码归结为上面的例子,我才意识到为什么回溯访问并不总是有效。自定义异常类的目的是收集异常的聚合计数,以便在下游对每个do_something的结果进行分类,例如:使用回溯是从WHERE记录异常被“引发”,因此创建异常(1/0 =虽然看起来不合适)使其能够工作。想知道如何使用检查模块而不是在回溯堆栈中考虑这个问题?

__main__
With each item in set:
    Try:
        do_something(item)
    except customException()
        clean up = log info etc.
end With
end.__main__

do_something(item)
    try:
        check_something()
    except customException
        if exception=typeA.1 raise customException(Type1)
        if exception=typeB.2 and item = ‘x’
            raise customException(Type2)

check_something()
    a = getInfo()
    unless getInfo()
        raise customException(typeA.1)
    try:
        b = getOtherInfo()
    except customException
        raise customException(typeB.2)
    …

2 个答案:

答案 0 :(得分:3)

如果我理解你的话,你会想知道为什么你的print "Stack trace within exception"行会打印getSub()的空列表,但会为getSub(True)打印一些追溯信息。

您的例外类__init__中有代码可通过sys.exc_info查看最新的异常。执行raise customException('test')时,customException('test')首先自行评估,然后才“知道”它将作为异常引发。因此,当你在getSub()中进行加注时,没有最近的异常。

使用getSub(True)时,会出现最新的异常,因为1/0会在创建customException之前引发异常。请注意,当您执行1/0时,最新的异常是来自该1/0的异常;你可以看到回溯中没有关于你的customException。

必须在引发异常之前创建异常对象。因此,您无法在异常类的__init__中查看“当前异常”,以获取有关在引发时创建的堆栈跟踪的信息,因为它尚未被创建当时还是提出来了。

如果需要,可以在创建异常对象时使用traceback.extract_stack来获取调用堆栈,但不能保证在引发异常对象时它与之有任何关系。仅仅因为创建了一个异常类的实例,甚至根本不会意味着它会被提升。对于某人来说,使用stuff = customException('blah')创建一个异常对象但从未真正提出异常,这是完全合法的(尽管通常毫无意义)。

无论如何,你的问题并不清楚你在这里想要达到的目的。如果你解释了它会有所帮助。

答案 1 :(得分:0)

因为您正在捕获异常,所以除非您明确重新提升

,否则不会有回溯
try:
    getSub(True)
except customException as e:
    print "customException2 was raised"
    raise    # add this to re-raise, with original traceback

或自己打印:

try:
    getSub(True)
except customException as e:
    print "customException2 was raised"
    print traceback.format_exc()