在捕获异常并重新抛出异常时,应该考虑哪些最佳实践?我想确保Exception对象的InnerException和堆栈跟踪被保留。下面的代码块在处理这个问题的方式上有区别吗?
try
{
//some code
}
catch (Exception ex)
{
throw ex;
}
Vs:
try
{
//some code
}
catch
{
throw;
}
在捕获异常并重新抛出异常时,应该考虑哪些最佳实践?我想确保Exception对象的InnerException和堆栈跟踪被保留。下面的代码块在处理这个问题的方式上有区别吗?
try
{
//some code
}
catch (Exception ex)
{
throw ex;
}
Vs:
try
{
//some code
}
catch
{
throw;
}
当前回答
如果你抛出一个带有初始异常的新异常,你也会保留初始堆栈跟踪。
try{
}
catch(Exception ex){
throw new MoreDescriptiveException("here is what was happening", ex);
}
其他回答
保存堆栈跟踪的方法是使用throw;这也是有效的
try {
// something that bombs here
} catch (Exception ex)
{
throw;
}
把交货;基本上就像从那个点抛出一个异常,所以堆栈跟踪只会到你发出throw ex的地方;声明。
Mike也是正确的,假设异常允许您传递一个异常(这是推荐的)。
Karl Seguin在他的编程基础电子书中也写了一篇关于异常处理的很棒的文章,非常值得一读。
编辑:编程基础的工作链接pdf。在文本中搜索“例外”即可。
我肯定会用:
try
{
//some code
}
catch
{
//you should totally do something here, but feel free to rethrow
//if you need to send the exception up the stack.
throw;
}
这将保护您的堆栈。
没有人解释过ExceptionDispatchInfo之间的区别。Capture(ex). throw()和一个普通的throw,所以它在这里。然而,有些人已经注意到了投掷的问题。
重新抛出捕获的异常的完整方法是使用ExceptionDispatchInfo。Capture(ex). throw()(仅在. net 4.5中可用)。
下面是测试这一点的必要情况:
1.
void CallingMethod()
{
//try
{
throw new Exception( "TEST" );
}
//catch
{
// throw;
}
}
2.
void CallingMethod()
{
try
{
throw new Exception( "TEST" );
}
catch( Exception ex )
{
ExceptionDispatchInfo.Capture( ex ).Throw();
throw; // So the compiler doesn't complain about methods which don't either return or throw.
}
}
3.
void CallingMethod()
{
try
{
throw new Exception( "TEST" );
}
catch
{
throw;
}
}
4.
void CallingMethod()
{
try
{
throw new Exception( "TEST" );
}
catch( Exception ex )
{
throw new Exception( "RETHROW", ex );
}
}
案例1和案例2将为您提供一个堆栈跟踪,其中CallingMethod方法的源代码行号是抛出新异常(“TEST”)行的行号。
然而,情形3将为您提供一个堆栈跟踪,其中CallingMethod方法的源代码行号是抛出调用的行号。这意味着如果抛出新的异常(“TEST”)行被其他操作包围,则您不知道异常实际上是在第几行抛出的。
情况4与情况2类似,因为原始异常的行号被保留,但不是真正的重抛出,因为它改变了原始异常的类型。
你也可以使用:
try
{
// Dangerous code
}
finally
{
// clean up, or do nothing
}
而抛出的任何异常都将上升到处理它们的下一层。
当抛出ex时,实际上是抛出了一个新的异常,并将错过原始的堆栈跟踪信息。Throw是首选的方法。