3层应用程序中的异常捕获最佳实践

4
我有一个包含以下3个层的WCF:
  1. 服务 (Service)
  2. 业务逻辑层 (BLL)
  3. 数据访问层 (DLL)
请问在以下场景中,哪一层最适合捕获并记录异常:

场景1:

DLL 中出现了异常。

场景2:

BLL 中出现了异常。

此外,在 Service 中调用 BLL 时,我是否应该始终使用 Try 和 Catch 来捕获异常?
2个回答

4
这取决于您的系统,但我会在BLL中记录异常,注意是“记录”而不是“捕获”!也就是说,在catch的末尾将会有一个重新抛出的过程!
服务中我根本不捕获任何东西——这只是与客户端通信的过程——我认为没有必要在其中放置任何逻辑。
当然:在抛出位置上捕获你预期的异常,并让未预期的异常通过。
例如: 场景1-可能捕获SqlExceptions,尝试处理它们,如果无法处理则将其包装在一些DAL-Exception中并抛出。 场景2-可能从第3层捕获DAL-Exceptions,看看是否可以处理它们或再次包装它们...。
我认为捕获和记录所有类型的未预料异常(catch (Exception))几乎永远不是一个好主意——应用程序状态在此之后将非常不确定。

感谢@Carsten König。WRAP、LOG和HANDLE之间有什么区别? - Nil Pun
包装:将许多不同的异常放入一个单独的异常中(作为内部异常或替换它们)- 优点:调用您的 BL 函数不需要知道 DAL 可能抛出的所有异常,只需知道包装器异常即可。/ 日志记录:仅记录异常并重新抛出 / 处理:捕获异常并进行一些明确定义的清理操作-不要重新抛出或抛出新异常-希望这可以帮助。 - Random Dev
嗨@Carsten,你能否澄清你的说法:“几乎从来不是一个好主意去处理、记录和静音所有类型的意外异常(catch(Exception))-这样做后应用程序状态将变得非常未定义。” - Nil Pun
当然,你经常会看到像 catch(Exception) { } 或者 catch(Exception) { /* log it */ } 这样的代码,它们捕获了所有可能出现的异常并继续执行。但是如果你仔细想一下,程序此时处于一个未知的状态 - 你不知道发生了什么,也不知道数据是否完好无损 - 所以最好通知用户并让程序停止运行 - 换句话说,不要捕获异常或重新抛出异常。 - Random Dev

3
请阅读MSDN上有关Microsoft Exception Handling Block的文章,它涵盖了很多场景并为您提供了一些良好的异常处理策略最佳实践,无论您是否使用异常处理块,如下图所示。

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接