python try 嵌套,关于错误处理:在Python中捕获嵌套异常

我有一组Python脚本,它们以嵌套的方式调用函数。对于这些函数中的每一个,我都有一个try,除了语句来捕获每个异常并打印它们。我想发送一封电子邮件警报,其中包含执行期间遇到的完整异常序列。例:

import sys

def SendAlert(ErrorMessage):

try:

#send email alert with error message

#[...]

except:

print(str(sys.exc_info()))

return(sys.exc_info())

def ParentFunction():

try:

#call ChildFunction

ChildResult = ChildFunction()

#do stuff with ChildResult

#[...]

return ParentResult

except:

ErrorMessage = str(sys.exc_info())

print(ErrorMessage)

SendAlert(ErrorMessage)

def ChildFunction():

try:

#do stuff

#[...]

return ChildResult

except:

print(str(sys.exc_info()))

return(sys.exc_info())

#main

if __name__ == '__main__':

Result = ParentFunction()

如果ChildFunction中出现错误,上面的代码将表现如下,这是最嵌套的函数:

ChildFunction遇到异常,它将打印并返回

错误消息到ParentFunction

ParentFunction将失败,因为ChildResult包含错误消息而不是有效值

ParentFunction将触发和异常,并在电子邮件警报中发送自己的错误消息

除了来自ParentFunction的错误消息之外,我希望电子邮件警报包含来自ChildFunction的错误消息。请注意,我想避免在ParentFunction的except语句中将ChildResult变量传递给SendAlert函数,因为在现实生活中我的程序有很多嵌套函数,这意味着将每个函数的结果变量传递给除了声明。

你会如何实现这一目标?有没有办法访问整个程序触发的完整错误序列?

谢谢

如何重新提高例外?

你什么意思?

为什么不使用try ... except Exception as error?

谢谢Chiheb,这也是Azat在下面推荐的。 我会尝试。

你不需要返回用sys.exc_info获得的异常:我们可以重新提升它

try:

# do stuff

# FIXME: we should avoid catching too broad exception

except Exception as err:

# do stuff with exception

raise err

所以你的例子看起来像

def SendAlert(ErrorMessage):

try:

# send email alert with error message

# [...]

pass

# what kind of exceptions may occur while sending email?

except Exception as err:

print(err)

raise err

def ParentFunction():

try:

# call ChildFunction

ChildResult = ChildFunction()

ParentResult = ChildResult

# do stuff with ChildResult

# [...]

return ParentResult

# FIXME: we should avoid catching too broad exception

except Exception as err:

ErrorMessage = str(err)

# why do we need to print again?

print(ErrorMessage)

SendAlert(ErrorMessage)

def ChildFunction():

try:

ChildResult = 0

# do stuff

# [...]

# let's raise `ZeroDivisionError`

ChildResult /= 0

return ChildResult

# FIXME: we should avoid catching too broad exception

except Exception as err:

print(err)

raise err

# main

if __name__ == '__main__':

Result = ParentFunction()

进一步改进

对于打印完整错误回溯,我们可以使用logging模块

import logging

logging.basicConfig(level=logging.DEBUG)

logger = logging.getLogger(__name__)

def SendAlert(ErrorMessage):

try:

# send email alert with error message

# [...]

pass

# what kind of exceptions may occur while sending email?

except Exception as err:

logger.exception('Error while sending email')

# we're not receiving values from this function

raise err

def ParentFunction():

try:

# call ChildFunction

ChildResult = ChildFunction()

ParentResult = ChildResult

# do stuff with ChildResult

# [...]

return ParentResult

# FIXME: we should avoid catching too broad exception

except Exception as err:

# this will log full error traceback

# including `ChildFunction`

logger.exception('Error in ParentFunction')

ErrorMessage = str(err)

SendAlert(ErrorMessage)

def ChildFunction():

ChildResult = 0

# do stuff

# [...]

# e. g. let's raise `ZeroDivisionError`

ChildResult /= 0

return ChildResult

# main

if __name__ == '__main__':

Result = ParentFunction()

它只是冰山一角,logging很棒,你绝对应该使用它。

进一步阅读

记录HOWTO,

SMTPHandler,用于通过SMTP发送电子邮件错误

感谢您的进一步改进,我刚刚测试了上面的脚本。一个问题,因为脚本正在重新提升并使用完整的异常序列记录ParentFunction中的异常,也许我不需要在ChildFunction中记录它?否则,日志会因为大量冗余而变得非常垃圾,因此可读性较差。你怎么看?

@ Alexis.Rolland:ofc你不应该两次记录相同的异常,所以随意删除ChildFunction内的记录

好的,对不起,如果这听起来是一个愚蠢的问题,但如果我自己删除了试试...除了来自ChildFunction的条款怎么办? ParentFunction仍然可以进行日志记录吗? (现在无法测试我在手机上)

我的意思是当然记录完整的异常序列...... :)

@ Alexis.Rolland:是的,它会起作用

@ Alexis.Rolland:完成答案,有什么可以改进的吗?

您还可以创建一个custom exception,它可以获取描述性错误消息并将其返回。

这是一个简单的例子,您可以修改它并将其实现到您的代码中,直到它满足您的需求:

class MyCustomError(Exception):

def __init__(self, err):

Exception.__init__(self)

self.error = err

def __str__(self):

return"%r" % self.error

a = 1

try:

if a != 0:

raise MyCustomError("This is an Error!")

except MyCustomError as err:

print(err)

输出:

'This is an Error!'

谢谢Chiheb,我对课程很陌生,请你详细说明它在这里的作用及其好处?

使用这种自定义异常(类),您可以轻松地跟踪代码中的错误,还可以在类中添加其他重复代码。例如,当存在异常时,您希望将错误记录到文件中,然后继续处理其余代码。或者,当存在异常时,您希望在执行其余代码之前调用方法/函数。没有限制......这也是将异常分类成组的一个方便的技巧。等等...

有关更多信息,请参见此处。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值