Python记录异常

时间:2011-08-09 21:09:35

标签: python exception logging design-patterns

我正在写一个包装类。我希望能够正确记录异常但允许调用方法知道发生的异常。我的班级看起来像这样:

import logging

log = logging.getLogger('module')

class MyAPIWrapper(library.APIClass):

    def __init__(self):
        self.log = logging.getLogger('module.myapiwrapper')


    def my_wrapper_method(self):
        try:
            response = self.call_api_method()
            return response.someData
        except APIException, e:
            self.log.exception('Oh noes!')
            raise e #Throw exception again so calling code knows it happened

我有点怀疑捕获和异常只是为了记录它然后重新提升它所以调用代码可以做些什么。这里的正确模式是什么?

2 个答案:

答案 0 :(得分:25)

捕获日志没有错。但是,我建议:

    try:
        response = self.call_api_method()
    except APIException, e:  # or 'as e' depending on your Python version
        self.log.exception('Oh noes!')
        raise #Throw exception again so calling code knows it happened
    else:
        return response.someData

只需执行裸raise即可保留完整的追溯信息。如果你在else子句中没有异常,那么放置代码也会更明确,并且更清楚你从哪个行捕获异常。

如果它正在处理错误,那么调用类也可以进行日志记录,但这对您的应用程序来说可能不方便。

修改:try ... except ... else ... finally的文档位于compound statements

答案 1 :(得分:6)

该方法是正确的,但您应该使用raise e而不是raise,这将自动重新引发最后一个异常。这也是少数情况下使用毯子except被认为是可接受的情况之一。

以下示例与您在Handling Exceptions上的Python文档中所做的非常相似:

  

最后一个except子句可以省略异常名称,以用作通配符。请谨慎使用,因为以这种方式很容易掩盖真正的编程错误!它还可以用于打印错误消息,然后重新引发异常(允许调用者也处理异常):

import sys

try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
except IOError as (errno, strerror):
    print "I/O error({0}): {1}".format(errno, strerror)
except ValueError:
    print "Could not convert data to an integer."
except:
    print "Unexpected error:", sys.exc_info()[0]
    raise