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