在C#中重新抛出异常

3

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

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”。我希望保留“From inside”消息。这个建议的更改将导致错误显示代码出现问题。 :/
2个回答

9
您不必将变量绑定到异常上:
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;
}

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

如果你不打算使用异常(例如将消息传递到其他地方),那么你不需要将其提取到变量中。你可以简单地捕获异常、执行自定义操作并抛出异常。


在某些情况下,我们确实会传递消息。例如,当查询验证失败时,在应用程序中常见的做法是throw new Exception("custom message");。然后将该消息转发给最外层的调用函数,以便更新用户界面以显示错误信息。 - jitendragarg
在这种情况下,你应该使用throw new exception("自定义消息", originalException),这样就不会丢失堆栈跟踪。 - Kyle Muir
1
为了精彩地使用 _pink_,你得到了 +1。 - user585968
等一下,现在我有一个新的问题。catch (System.Exception ex) { throw new System.Exception(ex); }不起作用。它给我一个错误,说最佳重载方法具有无效的参数。它确实需要一个错误消息。 - jitendragarg
1
关于这段代码:catch (Exception ex) { throw new Exception(ex.Message, ex); },不过值得思考的是:如果你抛出一个带有与原始异常相同信息的新异常 - 你为什么要这样做呢? - Kyle Muir
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接