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