我提到过,尽可能将错误处理逻辑移动到应用程序调用栈的更高层次有一个好处,那就是你的应用程序代码可以让这些错误自然冒泡而不必显式捕获它们,从而使代码更易于维护和阅读。
将大部分错误处理代码集中到应用程序的一个独立部分的另一个好处是,你可以更好地控制应用程序如何应对错误。最好的例子就是你可以多么容易地改变应用程序在生产环境和开发环境中的错误行为。
在开发过程中,应用程序崩溃并显示堆栈跟踪实际上并没有任何问题。实际上,这是一件好事,因为你希望错误和缺陷被注意到并被修复。但当然,相同的应用程序在生产环境中必须坚如磐石,错误被记录,如果可行的话,通知开发者,而不向最终用户泄露任何内部或私有的错误细节。
当错误处理逻辑集中且与应用程序逻辑分离时,这变得容易实现。让我们回到我前面分享的命令行示例,但现在让我们添加开发和生产模式:
import sys
mode = os.environ.get("APP_MODE", "production")
def my_cli()
# ...
if __name__ == '__main__':
try:
my_cli()
except Exception as error:
if mode == "development":
raise # in dev mode we let the app crash!
else:
print(f"Unexpected error: {error}")
sys.exit(1)
这是不是很棒?在开发模式下,我们现在重新抛出异常以导致应用程序崩溃,这样我们就可以在工作时看到错误和堆栈跟踪。但我们这样做的同时,并没有削弱生产版本的稳定性,它继续捕获所有错误并防止崩溃。更重要的是,应用程序逻辑不需要了解这些配置上的差异。
这是否让你想起了 Flask、Django 以及其他 Web 框架的某些特性?许多 Web 框架都有一个开发或调试模式,它们会在你的控制台甚至有时直接在 Web 浏览器中展示错误。这和我在一个假想的命令行应用程序中展示给你的解决方案是一样的,只不过应用到了 Web 应用程序上!
Source: https://blog.miguelgrinberg.com/post/the-ultimate-guide-to-error-handling-in-python?continueFlag=b823af05b30aef7a20891a583f4991f6