【发布时间】:2011-08-11 07:39:24
【问题描述】:
我编写了一个三层 Web 应用程序。 DAL BLL 和 web 表示层,每一层都有方法,所以问题是我应该在哪里捕获异常(使用 try catch),在 web?BLL?还是 DAL?为什么?谢谢。
【问题讨论】:
我编写了一个三层 Web 应用程序。 DAL BLL 和 web 表示层,每一层都有方法,所以问题是我应该在哪里捕获异常(使用 try catch),在 web?BLL?还是 DAL?为什么?谢谢。
【问题讨论】:
异常是任何方法的接口的一部分。
int doSomeThing( ... ) throws Some exceptions
异常可能是显式的,如 Java 的 Checked Exceptions 中一样,也可能是隐式的。尽管如此,调用者必须预见异常并决定要做什么——有时一个方法可能决定只是允许异常传播,你调用的东西的异常成为你正式接口的一部分。
我的做法:
因此,在 Web/Presentation 层,我们捕获所有异常并向用户显示友好的消息。往往会有少量的常见场景:
我发现在这些情况下,UI 有时会以不同的方式显示错误信息,因此我喜欢区分它们。这导致我设计我的业务逻辑接口来抛出相应的异常:TransientException、AuthorisationException、InvalidRequestException。
InvalidRequestException 往往具有有用的负载来帮助 UI 格式化有用的响应。
TransientException 可以包含技术信息(例如 DB XXX 有问题 YYY),但不是为了向用户显示,而是在分布式系统中作为诊断的辅助。
业务逻辑层负责从较低层捕获无数问题并为 UI 生成异常。
数据访问层应该遵循First Failure Data Capture的原则:捕获问题详细记录错误并抛出一些合适的异常。
【讨论】:
最好在数据库层捕获异常并将其抛到业务层,而不是从业务层抛到表示层。
我使用 throw 关键字重新抛出异常,并且不向用户显示异常,只是使用 LOG4NET 或在文件中显示错误消息和记录异常,这对你来说很容易。
您可以查看这篇文章如何在不隐藏细节的情况下抛出异常:Handle Exception Carefully
【讨论】:
除非您确定要处理错误,否则不要在所有方法中使用 try catch。您可能可以在 DAL 中使用 catch,记录异常并将其抛出层。
看到这个帖子Exception handling
【讨论】:
Pranay Rana 给出的链接描述了从层传播异常的正确方法,但是,除非您需要对异常采取一些措施,否则没有必要在底层层(DAL、BAL)中扭曲 try catch 中的方法.
当在退出方法之前必须执行某些代码段时,将方法包装在 try catch 中,例如在退出之前清理 SQL 连接/资源。像
这样扭曲你的方法Try
{
}
Catch
{
throw;
}
finally
{
//Mandatory code segment
}
确保将调用(在 UI 或任何其他层中)包装在 try catch 中。异常将在调用点被捕获,即使底层的方法没有被包裹在 try catch 中。
【讨论】: