缺点是捕获所有异常(在最高程序级别,然后重新提升,只是在退出之前记录?)

emd*_*ash 5 python exception

我在远程计算机上有一个长时间运行的程序,并希望确保(1)我有任何导致它终止的异常的记录,以及(2)如果终止,则通知某人.有没有人看到我使用的方法的缺点?(或建议更好的?)

我在这里阅读了Python文档和许多与例外相关的帖子,并了解毯子除了子句通常是个坏主意.在子例程和模块中我总是使用除了处理特定的预期异常,但是在程序的最高级别有一个"catch-all"except子句似乎很有用,以确保我可以在程序退出之前记录异常.

你怎么看?

import traceback
try:
    # main program code here
except BaseException:
    tb = traceback.format_exc()
    msg = "Exiting program due to exception:" + tb
    LogToFile(msg)         # custom logging function
    SendAlertEmail(msg)    # warn admin that program terminated
    raise                  # program exits with the existing exception
Run Code Online (Sandbox Code Playgroud)

请注意,我使用的是BaseException而不是Exception,因为如果终端上有人按下Ctrl-C,我想将其记录为退出程序的原因(并提醒管理员该程序已退出).但我想我也可以使用:

except Exception, KeyboardInterrupt:
Run Code Online (Sandbox Code Playgroud)

Ale*_*lli 7

有没有具体的缺点,但有一个很好的替代- sys.excepthook.

在您的特定版本中,请考虑使用裸except:,并sys.exc_info()获取异常信息; 这将确保你捕获一切-甚至怪异的情况下一些模块提出了一些别的比的子类的实例BaseException.例如:

>>> class X: pass
... 
>>> raise X
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
__main__.X: <__main__.X instance at 0xc9ad0>
Run Code Online (Sandbox Code Playgroud)

正如你看到的,它仍然有可能提高的东西except BaseException:就抓不住-这就是为什么裸除了except:仍然存在(特别是对非常特殊的用途,比如你的!).

无论您是使用钩子,还是构建自己的钩子,都要考虑(可能取决于配置标志或环境设置)不会给最终用户带来所有细节负担(就像改善用户体验一样简洁!),只是一个有意义的总结(向用户保证已记录问题的所有细节等等).