我有一个 WCF svc,分为服务层、业务逻辑层和数据访问层。
当我的 DAL 遇到异常时,我应该在那里捕获它还是让它冒泡回到服务层?为什么?
请忽略此方案的任何客户参与,我只关心在 WCF svc 上记录异常。
我有一个 WCF svc,分为服务层、业务逻辑层和数据访问层。
当我的 DAL 遇到异常时,我应该在那里捕获它还是让它冒泡回到服务层?为什么?
请忽略此方案的任何客户参与,我只关心在 WCF svc 上记录异常。
有一个术语 - 异常屏蔽。基本上,您应该防止 SYSTEM 异常到达更高级别,因为这可以让攻击者了解您的系统架构。WCF Exception Shielding 可以捕获特定类型的异常并用其他类型的异常替换它们。例如,它可以捕获 StackOverflow 异常并将其替换为您的自定义 SystemException。如果您使用企业库,您还可以配置在替换它们时记录这些异常
我想这取决于服务的使用方式以及发生异常时要让谁(如果有的话)知道。
例如,如果您正在开发一个关键任务的内部业务应用程序,您可能希望异常的详细信息通过服务层传递到使用该应用程序的用户界面,以便最终用户可以联系开发人员快速解决问题。
但是,假设您的服务被公共网页使用。您可能仍然希望服务层以某种方式捕获错误,但您可能会选择将最少的信息传递给最终客户端,向最终用户提供通用错误消息,并将异常的详细信息写入错误日志以开发商审查。
最后,我仍然认为您希望异常冒泡到服务层,但是您如何处理异常并决定将哪些信息传递给最终客户端取决于您。
它还取决于您如何构建解决方案。例如,如果 DAL 和 BLL 层是完全独立的组件,那么它们就不能对谁在调用它们做出假设。因此,它们都应该在组件边界上捕获异常,记录这些异常,然后允许异常传播。他们可能希望将一般异常包装在特定于层的异常中:
catch (Exception ex)
{
Logger.Log(ex);
throw new DalException("Unhandled exception in DAL", ex);
}
如果您知道这些只会用作整个应用程序的一部分,那么您可以将日志记录推迟到最外层 - 如果它没有捕获异常,则不会记录异常。
System.ServiceModel.Dispatcher.IErrorHandler
我通常使用配置文件中的 ServiceBehavior 附加到 Web 服务的通用错误处理程序(实现)。
该IErrorHandler.ProvideFault
方法拦截从服务抛出的异常,并且:
记录它们;
按原样传递 FaultExceptions;
将 BLL 抛出的“业务”异常(例如违反业务规则)转换为带有错误代码“发送方/客户端”的 FaultExceptions;
将技术异常(例如由 DAL 抛出)转换为具有故障代码“接收器/服务器”的 FaultExceptions。
这样服务代码本身只包含业务代码,不需要捕获任何异常。