【问题标题】:Rethrowing an exception in C# [duplicate]在 C# 中重新引发异常 [重复]
【发布时间】:2016-05-11 08:14:47
【问题描述】:

我有一些代码可以捕获异常,回滚事务,然后重新抛出异常。

catch ( Exception exSys )   {
    bqBusinessQuery.RollBackTransaction();
    throw exSys ;
}

如果我使用这段代码,VS Code 分析会抛出警告说

改为使用不带参数的“throw”,以保留最初引发异常的堆栈位置。

如果我使用代码

catch ( Exception exSys )   {
    bqBusinessQuery.RollBackTransaction();
    throw;
}

然后我收到警告说

变量“exSys”已声明但从未使用过

我应该如何解决这个问题?

编辑 我试过这个方法,但它不起作用。 system.exception 类需要额外的消息以及内部异常。如果我这样做,它将抛出一条新消息,覆盖来自原始异常的消息。我不想得到新的异常,我想用相同的消息抛出相同的异常。

    catch (System.Exception ex)
    {
        throw new System.Exception(ex);
    }

编辑

        catch (System.Exception ex)
        {
            throw new System.Exception("Test",ex);
        }

试过这个方法。然后使用throw new Exception("From inside"); 手动引发异常。现在,ex.Message 返回“Test”而不是“From inside”。我想保持“来自内部”的信息不变。这个建议的更改将导致到处出现错误显示代码的问题。 :/

【问题讨论】:

    标签: c# exception-handling try-catch rethrow


    【解决方案1】:

    您不必将变量绑定到异常:

    try
    {
        ...
    }
    catch (Exception) 
    {
        bqBusinessQuery.RollBackTransaction();
        throw;
    }
    

    实际上,在您的情况下,当您捕获任何异常时,您甚至不必命名异常类型:

    try
    {
        ...
    }
    catch
    {
        bqBusinessQuery.RollBackTransaction();
        throw;
    }
    

    或者(如@Zohar Peled 建议的那样)抛出一个新异常,将捕获的异常用作内部异常。这样,您既可以保留堆栈,又可以为异常提供更多上下文。

    try
    {
        ...
    }
    catch (Exception e)
    {
        throw new Exception("Transaction failed", e);
    }
    

    如果您确实想将异常用于某些处理(例如记录它),但又想原封不动地重新抛出它,请声明变量,但使用普通的throw

    try
    {
        ...
    }
    catch (Exception e)
    {
        Console.WriteLine(e.Message);
        throw;
    }
    

    【讨论】:

      【解决方案2】:
      catch (Exception)   
      {
          bqBusinessQuery.RollBackTransaction();
          throw;
      }
      

      如果您不打算使用异常(例如在某处传递消息),则无需将其拉出到变量中。您可以简单地捕捉、做自定义的事情并扔掉。

      【讨论】:

      • 我们在某些情况下会传递信息。例如,当查询验证失败时,throw new Exception("custom message"); 在应用程序中很常见。然后将相同的内容转发到最外层的调用函数,该函数更新 UI 以显示错误。
      • 在这种情况下你应该throw new exception("custom message", originalException) 这样你就不会丢失堆栈跟踪
      • 对于 pink 的出色使用,您将获得 +1
      • @KyleMuir 我可以做throw new exception(originalException)。我不想添加任何新消息,只是保留第一次发生异常时的原始消息。例如。 execute query 函数抛出异常说primary key already exists,然后我只想回滚事务并让相同的异常消息通过。
      • 怎么样:catch (Exception ex) { throw new Exception(ex.Message, ex); } 然而,值得深思的是:如果你抛出一个新的异常,其信息与原始异常相同 - 你为什么要这样做?
      猜你喜欢
      • 2020-07-14
      • 1970-01-01
      • 2021-10-04
      • 1970-01-01
      • 2011-09-12
      • 1970-01-01
      • 2012-01-13
      • 2013-02-23
      • 2020-12-30
      相关资源
      最近更新 更多