我正在尝试用Python编写高度可靠的代码。我遇到的最常见的问题是,运行一段时间后,会发生一些边缘情况并引发一个我没有处理过的异常。这通常发生在使用外部库时 - 如果没有阅读源代码,我不知道一种简单的方法来获取使用特定库函数时可能引发的所有异常的列表,因此很难知道要处理什么。我知道使用catch-all处理程序是不好的做法,所以我没有这样做。
这有一个很好的解决方案吗?看起来静态分析工具应该可以检查是否处理了所有异常,但我还没有找到。这存在吗?如果没有,为什么? (这是不可能的?一个坏主意?等)我特别希望它能够分析导入的代码,原因如上所述。
答案 0 :(得分:2)
很棒的问题。
您可以尝试静态处理问题(例如,通过引入自定义flake8
规则?),但是,我认为,它是测试和测试覆盖范围的问题。我会通过添加更多"否定路径" /"错误处理"来解决问题。检查/测试使用第三方软件包的地方,在需要时引入模拟副作用并同时监控覆盖率报告。
我还会研究Mutation Testing想法(查看Cosmic Ray Python包)。我不确定是否可以将突变体配置为也抛出异常,但看看它是否有用。
答案 1 :(得分:2)
"使用全能处理程序"这是不好的做法。 忽略异常:
我们的网络服务有一个包装主循环的除外。
except:
log_exception()
attempt_recovery()
这很好,因为通知我们(必要)意外错误,然后尝试恢复(不必要)。然后我们可以查看这些日志并找出问题所在,以便我们可以阻止它再次发生我们的常规异常。
您希望避免:
except:
pass
因为忽略了错误 ...然后您就不知道发生了错误,并且您的数据可能已损坏/无效/已经/被偷走了。您的服务器可能上/下/着火。我们不知道因为我们忽略了这个例外。
Python并不需要注册可能抛出的异常,因此不会检查模块可能抛出的所有异常,但是大多数异常都会让您知道应该准备好在文档中处理什么。根据您的服务,当它收到未处理的异常时,您可能希望:
注意一个趋势?行动发生了变化,但你永远不想忽视它。
答案 2 :(得分:0)
不是试图处理所有异常,而是如你所描述的那样非常困难,为什么不抓住所有异常,而是排除一些,例如你在评论中提到的KeyboardInterrupt
?