收集错误和发送摘要的最佳方法是什么?

时间:2016-09-29 10:33:16

标签: python

我有一个脚本依次执行几个独立的功能。我想收集在此过程中发生的错误/异常,以便发送包含错误摘要的电子邮件。

在允许脚本完成并完成所有步骤的同时,提出这些错误/异常并收集它们的最佳方法是什么?它们是独立的,所以如果一个崩溃并不重要。其余的仍然可以运行。

def step_1():
    # Code that can raise errors/exceptions

def step_2():
    # Code that can raise errors/exceptions

def step_3():
    # Code that can raise errors/exceptions

def main():
    step_1()
    step_2()
    step_3()

    send_email_with_collected_errors()

if '__name__' == '__main__':
    main()

我应该在main()函数的try..except块中包装每一步吗?除了错误收集器之外,我应该在每个步骤函数上使用装饰器吗?

3 个答案:

答案 0 :(得分:3)

您可以将每个函数包装在try / except中,通常更适合小型简单脚本。

def step_1():
    # Code that can raise errors/exceptions

def step_2():
    # Code that can raise errors/exceptions

def step_3():
    # Code that can raise errors/exceptions

def main():
    try:
        step_1_result = step_1()
        log.info('Result of step_1 was {}'.format(result))
    except Exception as e:
        log.error('Exception raised. {}'.format(e))
        step_1_result = e
        continue
    try:
        step_2_result = step_2()
        log.info('Result of step_2 was {}'.format(result))
    except Exception as e:
        log.error('Exception raised. {}'.format(e))
        step_2_result = e
        continue

    try:
        step_3_result = step_3()
        log.info('Result of step_3 was {}'.format(result))
    except Exception as e:
        log.error('Exception raised. {}'.format(e))
        step_3_result = e
        continue


    send_email_with_collected_errors(
        step_1_result,
        step_2_result,
        step_3_result
    )

if '__name__' == '__main__':
    main()

对于更精细的内容,您可以使用装饰器来构建捕获的错误/异常列表。例如

class ErrorIgnore(object):
   def __init__(self, errors, errorreturn=None, errorcall=None):
      self.errors = errors
      self.errorreturn = errorreturn
      self.errorcall = errorcall

   def __call__(self, function):
      def returnfunction(*args, **kwargs):
         try:
            return function(*args, **kwargs)
         except Exception as E:
            if type(E) not in self.errors:
               raise E
            if self.errorcall is not None:
               self.errorcall(E, *args, **kwargs)
            return self.errorreturn
      return returnfunction

然后你可以像这样使用它:

exceptions = []

def errorcall(E, *args):
    print 'Exception raised {}'.format(E)
    exceptions.append(E)

@ErrorIgnore(errors=[ZeroDivisionError, ValueError], errorreturn=None, errorcall=errorcall)
def step_1():
   # Code that can raise errors/exceptions

...

def main():
    step_1()
    step_2()
    step_3()

    send_email_with_collected_errors(exceptions)

if '__name__' == '__main__':
    main()

答案 1 :(得分:0)

使用简单的try except语句并记录异常,这些异常是收集所有错误的标准方法。

答案 2 :(得分:0)

有两种选择:

  1. 使用装饰器捕获所有异常并将其保存在某处。
  2. 添加try / except无处不在。
  3. 使用装饰器可能会更好更清洁,代码也更容易维护。

    如何存储错误?你的决定。您可以将它们添加到某个列表中,创建记录类接收异常并在完成所有操作后获取它们...取决于您的项目和代码大小。

    简单的日志记录类:

    class LoggingClass(object):
        def __init__(self):
            self.exceptions = []
    
        def add_exception(self, exception):
            self.exceptions.append(exception)
    
        def get_all(self):
            return self.exceptions
    

    在脚本中创建类的实例,在decorator中捕获异常并将它们添加到类中(但是全局变量也可以)。