异常处理是一件大事,为此设计一个好的策略并不简单。
首先,一些一般规则:
- 运行代码时出现异常完全不能继续,所以也许它尝试处理一些内部异常但最终失败了。想想 TCP 连接:如果损坏的数据包到达,这是一个异常,但 TCP 协议可以处理它。如果损坏太多,则会引发 I/O 或套接字异常
- 例外不可能总是存在handled。在几乎所有情况下,当您从底层获得异常时,您将无法运行纠正代码。如果您的应用程序依赖于数据库并且该数据库处于离线状态,那么当您收到有关它的异常时,您只能显示一条错误消息
- 异常可能是意外的,并且可能揭示设计或实现缺陷。例如,实现缺陷可能是这样的情况:您有一个冗余数据库,但当您无法连接到第一个镜像时,您不会尝试使用第二个镜像
对于第三点,重要的是log异常并定期分析日志以发现任何奇怪的情况。那么,让我们从具体的答案开始。
首先
考虑“处理”异常。当您编写每一行代码时,请考虑可能阻止其完成的可能问题,并且考虑可能的纠正措施。如果有可能的话。错误消息不是一个好的处理方式,它是最新的策略。
不要开始写try-catch(Exception),而是更喜欢特定的异常。如果您需要将字符串解析为数字等,那么期望FormatException
,如果您需要从Object
根据您的类型期望InvalidCastException
当你编写较低层时
不要犹豫抛出异常!不要像很多人那样做,即。return null
或使用(如 ANSI C)布尔返回值和引用参数。但也有例外。如果您可以处理异常(即您找不到本地文件,但您知道您有远程备份,因此请处理FileNotFoundException
通过调用远程镜像,但如果仍然无法连接,则最终抛出)然后执行此操作并尝试恢复计算,但如果无法连接,则抛出。并且不要忘记抛出内部异常(如果存在),因为它有助于记录最高层。
基本上,即使您没有捕获任何异常,您仍然可以决定自己抛出异常!强烈建议这样做,尤其是当函数参数无效时!
另一个不错的选择是仍然登录底层。无论发生异常,您实际上都想记录日志。
当您登录时
请记住对消息给予足够的严重性。如果您通过代码发现数据库处于离线状态,这并不是意外异常。仍将其记录为错误,但在调查日志时不必担心代码错误。相反,如果您捕获代码无法识别的异常(NullReferenceException
是一个经典的例子)然后以最高严重性记录,即。致命的,给它最高优先级!
ASP.NET 的好策略
肯定可以基于Page.OnError
方法。如果您网站的所有页面都有一个基页面类,那么您绝对应该重写该方法。在该方法中,您应该首先log你的例外。
您也不应该滥用 try-catch(Exception) 块,因为如果您没有捕获无法使用 catch 处理的异常,您will必须通过 OnError 来处理它。
当你运行这样的方法时,不要立即想到Server.RemoveError()
。您可能更喜欢使用一个针对 HTTP 500 错误(当未处理的异常冒泡到 ASP.NET 运行时时触发)的静态 HTML 页面,该页面向用户显示礼貌消息。
Briefly
- 不要犹豫
throw
如果发生任何奇怪的事情,在底层
- 正如您的建议所述,不要处理您无法处理的异常(如果您捕获了无法处理的异常,请重新抛出它)
- 日志!!!!!!!!!!!!!!!!!
- 不要在公共网站上向最终用户透露异常详细信息,永远不要!默认情况下,ASP.NET 会阻止这种情况发生,但您仍然可以使用 OnError 来打印堆栈跟踪
- Use
OnError
, or Application_Error
as 单一中心点处理所有意外的异常
- 定期检查日志中的错误/致命消息,以查找代码问题,然后考虑维护/调试/修复它