Mono:如何(重新)抛出异常,保留原始堆栈跟踪信息并收集本地数据
本文关键字:信息 跟踪 数据 堆栈 原始 如何 重新 保留 抛出异常 Mono | 更新日期: 2023-09-27 18:01:14
我递归地处理分层数据。如果出现问题,我想收集堆栈展开的额外信息(导致异常的节点路径(。我想保留原始的异常消息和堆栈跟踪。这应该是一个很受欢迎的任务,但我在.NET中找不到任何支持。我该如何实现它?
我试图捕捉异常并重新引发我自己的异常,在递归函数中提供额外的数据,或者在原始异常exception.data中存储额外的数据。问题是我没有设法提供正确的堆栈跟踪,其中应该包括原始异常堆栈跟踪+我的递归函数调用的堆栈跟踪展开到我处理异常的地方。
我的代码看起来像:
void func(...)
{
try
{
...
func(...);
}
catch (Exception ex)
{
Rethrow(ex, localData);
}
}
Rethrow()
如何实现?
编辑:
我发现这种情况只发生在Mono中,而不是.NET中。是的,在.NET中throw;
工作得很好。在Mono中没有,至少在我使用的版本中没有(Unity3D的Mono 2.8的自定义构建(。示例:
static void CheckRethrow()
{
try
{
f(0);
}
catch (Exception ex)
{
Debug.LogException(ex);
}
}
static void f(int i)
{
try
{
if (i > 3)
throw new Exception("some message");
f(++i);
}
catch (Exception ex)
{
throw;
}
}
输出调用堆栈:
f (Int32 i) (at Test.cs:18)
CheckRethrow() (at Test.cs:9)
正如您所看到的,在这个调用堆栈中缺少对f()
的几个调用。
在.NET中,几乎所有异常都有一个名为InnerException
的成员。这样可以有多个异常或一系列异常。
void func(...)
{
try
{
...
func(...);
}
catch (Exception ex)
{
throw new MyOwnExceptionWithLocalData(localData, ex);
}
}
或者,尽管我还没有测试过它,但您可以向异常添加信息,并通过不提及变量来保留它的堆栈跟踪:
void func(...)
{
try
{
...
func(...);
}
catch (Exception ex)
{
ex.Property = value;
throw; // Note: no variable name here, will throw last exception and preserve stack trace
}
}
只需使用键投掷
try {
} catch (Exception ex){
throw;
}