【发布时间】:2016-09-02 18:13:59
【问题描述】:
我有一个组件使用返回值而不是标准异常处理来处理错误。除了错误代码之外,它还返回错误发生位置的堆栈跟踪。我用来调用组件的包装器会解释返回码并抛出异常。
我想让包装器抛出一个异常,其中包括从组件捕获的堆栈跟踪信息。我希望它看起来好像异常是从错误的原始站点抛出的,即使它是在其他地方抛出的。 更具体地说,我希望 Visual Studio 测试运行程序显示的堆栈跟踪能够反映正确的位置。
有没有办法做到这一点?如果我能避免访问私有成员的低级反射技巧也很好,但我会尽我所能。
我不关心如何捕获堆栈跟踪,我关心的是将已捕获的堆栈跟踪附加到异常。
我尝试覆盖 StackTrace 属性,但 Visual Studio 正在从其他地方提取堆栈跟踪数据,并且似乎完全忽略了被覆盖的属性
CustomException GenerateExcpetion()
{
return new CustomException();
}
void ThrowException(Exception ex)
{
Trace.WriteLine("Displaying Exception");
Trace.WriteLine(ex.ToString());
var edi = ExceptionDispatchInfo.Capture(ex);
edi.Throw();
}
[TestMethod]
public void Test006()
{
var ex = GenerateExcpetion();
ThrowException(ex);
}
public class CustomException : Exception
{
string _stackTrace;
public CustomException()
{
_stackTrace = Environment.StackTrace;
}
public override string StackTrace
{
get
{
return base.StackTrace;
}
}
}
Exception.ToString() 方法从私有属性中提取堆栈跟踪数据,因此不会显示来自覆盖的堆栈跟踪。
CustomException:引发了“CustomException”类型的异常。
ExceptionDispatchInfo 也会从私有属性中查找堆栈跟踪数据,因此它无法找到任何数据,并且当您抛出此自定义异常时,新的堆栈跟踪会附加到异常的位置它被抛出。如果直接使用throw,则将私有堆栈信息设置为发生throw的地方。
【问题讨论】:
-
你为什么不一起放弃错误代码?
-
@EmperorAiman 我猜它是第三方组件?
-
@adjan,那一定是 90 年代的。