如何在c#/ .net中logging抛出的exception
我目前正在编写一个小的框架,供公司内其他开发人员内部使用。
我想提供良好的Intellisense信息,但是我不确定如何logging抛出的exception。
在以下示例中:
public void MyMethod1() { MyMethod2(); // also may throw InvalidOperationException } public void MyMethod2() { System.IO.File.Open(somepath...); // this may throw FileNotFoundException // also may throw DivideByZeroException }
我知道loggingexception的标记是:
/// <exception cref="SomeException">when things go wrong.</exception>
我不明白的是如何logging由 MyMethod1()
调用的代码抛出的exception?
- 我应该logging由
MyMethod2()
抛出的exception - 我应该logging
File.Open()
抛出的exception吗?
什么是logging可能的例外的最好方法?
你应该logging你的代码可能抛出的每个exception,包括你可能调用的任何方法中的exception。
如果列表有点大,您可能需要创build自己的exceptiontypes。 抓住你可能在你的方法中遇到的所有的东西,把它们包装在你的exception,并抛出。
另一个你可能想要这样做的地方是,如果你的方法是在你的API的表面上。 就像一个Facade将多个接口简化为一个接口一样,您的API应该将多个exception简化为一个exception。 使调用者更容易使用您的代码。
为了回答Andrew的一些担忧(从评论中),有三种types的例外情况:你不知道的,你知道的,不能做任何事的,你知道的,可以做的。
那些你不知道的你想放手。 它的快速失败的原因 – 更好的是你的应用程序崩溃,而不是进入最终会破坏数据的状态。 崩溃会告诉你发生了什么事情,为什么,这可能有助于将这个例外排除在“你不知道的事情”列表之外。
那些你知道的并且不能做任何事情的是exception,比如OutOfMemoryExceptions。 在极端的情况下,你可能想要处理像这样的exception,但是除非你有一些相当出色的要求,否则就把它们当作第一类 – 让我们走吧。 你必须logging这些例外吗? 你会看起来非常愚蠢的logging每一个新方法的对象的方法OOMs。
那些你知道的,可以做的事情是你应该logging和包装的。
你可以在这里find更多关于exception处理的指导。
您应该使用标准的xml文档 。
/// <exception cref="InvalidOperationException">Why it's thrown.</exception> /// <exception cref="FileNotFoundException">Why it's thrown.</exception> /// <exception cref="DivideByZeroException">Why it's thrown.</exception> public void MyMethod1() { MyMethod2(); // ... other stuff here } /// <exception cref="FileNotFoundException">Why it's thrown.</exception> /// <exception cref="DivideByZeroException">Why it's thrown.</exception> public void MyMethod2() { System.IO.File.Open(somepath...); } /// <exception cref="FileNotFoundException">Why it's thrown.</exception> public void MyMethod3() { try { MyMethod2(); } catch (DivideByZeroException ex) { Trace.Warning("We tried to divide by zero, but we can continue."); } }
这样做的价值在于您提供了可能发生的已知exception的文档。 如果您正在使用Visual Studio,并且可以在稍后提醒您(或其他人)可以预料到的例外情况,则可以在智能感知中使用此文档。
您要指定特定的exceptiontypes,因为您可能能够处理一种types的exception,而其他types是严重问题的结果并且不能被纠正。
通过使用几个优秀的插件,可以使您的文档处理变得更加简单。 其中之一就是GhostDoc ,它是Visual Studio的免费插件,可以生成XML-doc注释。 另外,如果您使用ReSharper ,请查看ReSharper优秀的Agent Johnson插件 ,该插件添加了一个用于为抛出的exception生成XML注释的选项。
更新:看来,阿让约翰逊是不可用的R#8,结帐例外ReSharper作为替代…
步骤1:GhostDoc生成XML注释(Ctrl-Shift-D),而ReSharper的Agent Johnson插件build议loggingexception:
第1步160wpb4.png
步骤2:使用ReSharper的快捷键(Alt-Enter)添加exception文档:
第2步http://i41.tinypic.com/osdhm
希望帮助:)
据我所知,使用<exception>元素的意图是在装饰方法时使用它,而不是例外:
/// <summary>Does something!</summary> /// <exception cref="DidNothingException">Thrown if nothing is actually done.</exception> public void DoSomething() { // There be logic here }
可以通过调用其他方法抛出的exception应该被捕获,处理并logging在这些方法中。 .NET可能抛出的exception,或者你自己的代码显式抛出的exception应该被logging下来。
就具体而言,也许你可以捕捉并抛出自己定制的exception?
你的方法的一部分合同应该是检查前提条件是否有效,所以:
public void MyMethod2() { System.IO.File.Open(somepath...); // this may throw FileNotFoundException }
变
/// <exception cref="FileNotFoundException">Thrown when somepath isn't a real file.</exception> public void MyMethod2() { FileInfo fi = new FileInfo( somepath ); if( !fi.Exists ) { throw new FileNotFoundException("somepath doesn't exists") } // Maybe go on to check you have permissions to read from it. System.IO.File.Open(somepath...); // this may still throw FileNotFoundException though }
通过这种方法,可以更容易地logging您明确抛出的所有exception,而不必logging可能抛出的OutOfMemoryException
等。
你应该logging你的方法可能抛出的所有exception。
为了隐藏实现细节,我会尝试自己处理来自MyMethod2的一些exception。
如果您无法处理或解决exception情况,您可以考虑重新启用它们。 大多数情况下打包/打包在一个更有意义的例外调用者。
事实上,正如已经回答的那样,loggingexception的方法是使用XML注释。
除了插件之外,您还可以使用可以与TFS集成的静态分析工具,以确保您有例外logging。
在下面的链接中,您可以看到如何为StyleCop构build一个自定义规则来validation您的方法抛出的exception正在被logging。
http://www.josefcobonnin.com/post/2009/01/11/Xml-Documentation-Comments-Exceptions-I.aspx http://www.josefcobonnin.com/post/2009/01/15/Xml-Documentation -Comments-例外,II.aspx
问候。
在你的方法中logging预期的exception,在你的例子中,我会让用户知道,该方法可以抛出一个文件没有发现exception。
请记住,它是告诉调用者什么期望,以便他们可以select如何处理它。