我应该采取什么方法来处理非通用异常

时间:2014-03-19 15:04:20

标签: c# .net exception try-catch

我编写了代码,为了防御目的,我在try-catch中将所有方法体包含在Exception块中的通用catch中。

现在我编写了接受类型为Exception的对象的方法,然后记录基本异常类型,异常消息和堆栈跟踪。然后迭代地遍历内部异常并为它们打印相同的内容。所以简而言之,无论发生什么异常,我都会在日志中获得所有嵌套异常的基类型,消息和堆栈跟踪。

我已经在Visual Studio向我发出警告的所有地方捕获了非泛型异常,因为异常未被捕获。但这些数量非常少。

然而,他们是在测试运行中的实例,在调用方法时:

  

ExchangeService.LoadPropertiesForItems()

我得到了跟踪堆栈跟踪

2014-03-18 16:59:09.3816 | Error | The request failed. Unable to connect to the remote server 

                  Immediate Stack Trace 
===================================================================================
Microsoft.Exchange.WebServices.Data.ServiceRequestException : The request failed. Unable to connect to the remote server
   at Microsoft.Exchange.WebServices.Data.ServiceRequestBase.GetEwsHttpWebResponse(IEwsHttpWebRequest request)
   at Microsoft.Exchange.WebServices.Data.ServiceRequestBase.ValidateAndEmitRequest(IEwsHttpWebRequest& request)
   at Microsoft.Exchange.WebServices.Data.MultiResponseServiceRequest`1.Execute()
   at Microsoft.Exchange.WebServices.Data.ExchangeService.FindItems[TItem](IEnumerable`1 parentFolderIds, SearchFilter searchFilter, String queryString, ViewBase view, Grouping groupBy, ServiceErrorHandling errorHandlingMode)
   at Microsoft.Exchange.WebServices.Data.ExchangeService.FindItems(FolderId parentFolderId, SearchFilter searchFilter, ViewBase view)
   at Microsoft.Exchange.WebServices.Data.ExchangeService.FindItems(WellKnownFolderName parentFolderName, ViewBase view)
   at com.cos.method() in c:\SW\Class.cs:line 268


     Inner Exception 1 : Stack Trace
-----------------------------------------------------------------------------
Unable to connect to the remote server
   at System.Net.HttpWebRequest.GetResponse()
   at Microsoft.Exchange.WebServices.Data.EwsHttpWebRequest.Microsoft.Exchange.WebServices.Data.IEwsHttpWebRequest.GetResponse()
   at Microsoft.Exchange.WebServices.Data.ServiceRequestBase.GetEwsHttpWebResponse(IEwsHttpWebRequest request)


     Inner Exception 2 : Stack Trace
-----------------------------------------------------------------------------
A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 10.40.7.29:443
   at System.Net.Sockets.Socket.EndConnect(IAsyncResult asyncResult)
   at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Exception& exception)

此方法的MSDN page未指定它可以抛出ServiceRequestException,Visual Studio也不会显示任何警告。

此外,我公司的自动代码分析工具为此类通用异常捕获块生成了大量警告。

我应该如何处理此类事件的发生?

1 个答案:

答案 0 :(得分:0)

将整个工作流程包装在try-catch中似乎是防止意外异常导致代码崩溃或导致意外下行影响的最佳方法。通常,它是一层安全性,模糊了您实际处理已知问题的特定异常的方式。

冒泡

至于何时起泡以及何时捕获异常的标准,请查看您的工作流程,当较高级别可能具有更好的上下文时,在较低级别方法中捕获异常可能没有意义关于如何处理特定的删除的决定。例如,我可能让算术函数抛出一个未处理的异常,以便我可以在调用它的服务中捕获它,这将更好地知道,我应该如何处理该特定异常,也许我会调用另一个函数,或者通过返回精炼的异常消息等。所有这些选项在低级方法中不一定可用或有意义。

多个异常处理

当您捕获异常时,通常最佳做法是捕获特定的excpetions并为上面的示例提供针对每个异常类型的单独处理ServiceRequestException泛型处理可能如下所示。

try{ 
//Do Your Work
}
catch(ServiceRequestException srex)
{
//Handle this Specific Exception Type
}
catch(StackOverflowException soex)
{
//Handle this Specific Exception Type
}
catch(SomeOtherSpecificException sose)
{
//Handle this Specific Exception Type
}
catch(Exception ex)
{
//Handle an Unexpected Exception
}

在这个异常定义中,我通过最具体到最不具体的顺序来命令我的异常。我确实在最后包含了泛型异常,但总是最好只捕获预期的特定异常,因为某些防止任何异常转义的用例可能是最重要的,例如Web开发永远不会想要例外逃避,改善用户体验。如果你必须使用cathc generic excpetion,请确保你有适当的异常记录。

异常记录

听起来你已经有了一种记录方法,但无论如何我都会提到这一点。 .NET log4Net有很多很棒的日志选项,Common.Logging是我经常使用的。还有Exception Specific记录器,如Elmah。需要注意的一件重要事情是,日志记录允许您指定各种级别和通信方法。这将允许将粒度应用于您的异常管理,因此异常(尤其是您预期可能发生的异常)可能会优先考虑通用的excpetions。能够将未正确处理的异常弹出到顶部,或使用电子邮件或更直接的异常通信形式,将有助于您更好地响应异常,并在代码中实现更好的异常处理。

如果确实发现意外异常,请确保为它们添加特定的catch方法,并进行异常处理。希望这可以帮助。这是一篇代码项目文章,其中有很多关于异常管理的1337专业提示,我在这里提到的那些我认为最符合你的问题,但这篇文章也值得一读。

http://www.codeproject.com/Articles/9538/Exception-Handling-Best-Practices-in-NET#Don%27teverswallowexceptions13