【问题标题】:Mono: How to (re)throw exception preserving original stack trace info and collecting local dataMono:如何(重新)抛出异常,保留原始堆栈跟踪信息并收集本地数据
【发布时间】:2014-04-30 16:34:02
【问题描述】:

我递归处理分层数据。如果出现问题,我想在堆栈展开时收集其他信息(导致异常的节点路径)。我想保留原始异常消息和堆栈跟踪。这应该是非常受欢迎的任务,但我在 .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() 的几个调用。

【问题讨论】:

    标签: c# exception exception-handling mono callstack


    【解决方案1】:

    在 .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
        }
    }
    

    【讨论】:

      【解决方案2】:

      只要用钥匙扔

      try {
      
      } catch (Exception ex){      
      
          throw;
      }
      

      【讨论】:

      • 这适用于.Net,但不适用于单声道。 (不确定最新的单声道更新。)
      猜你喜欢
      • 2011-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-02
      • 2017-05-02
      相关资源
      最近更新 更多