5

我有一个常见的异常处理函数:

public static void ManageException(Exception ex,
                                   string customErrorMsg,
                                   bool displayMessage)

我想从一些 catch 块中调用它。

处理异常后,我想重新抛出异常,同时保留堆栈跟踪。

我在某处读到我应该throw在没有任何参数的情况下声明。该throw语句(没有任何参数)在一个catch块中工作正常,但在我的ManageException函数中,它给了我一个编译错误:

不允许在 catch 子句之外使用不带参数的 throw 语句

是否有任何解决方案可以从函数中重新抛出整个堆栈跟踪的异常并且没有任何性能影响ManageException

我正在使用 C# 2.0。

4

5 回答 5

6

您必须指定要抛出的异常,如下所示:

throw ex;

如您的错误中所述,您只能throw;从 catch 块内重新抛出异常(使用 )。恕我直言,这确实是唯一有意义的地方;您要么捕获异常,要么抛出异常,并且可能不应该两者都做。从一个名为 的方法ManageException中,我想知道您为什么要管理所述异常,但无论如何都要抛出它。

也许您想将原始异常包装在您自己的异常中,提供更多详细信息?在这种情况下,如果您想保留该数据,我将使用exas抛出一个新异常。InnerException


根据您的评论,如果您要做的是确定是否应该重新抛出异常,我建议:

  • 将您的方法重命名为TryManageException并更改签名以返回 a bool- 如果异常未正确管理并且需要重新抛出,则返回 false;如果已处理,则返回 true。
  • 如果该方法返回 false(= 未管理),请从 catch 块中重新抛出或执行您需要的任何其他操作:

    try
    {
        decimal oops = 5 / 0;
    }
    catch (Exception e)
    {
        if (!CommonExceptionHandler.TryManageException(e, "oops", "oops"))
            throw;
    }
    
于 2013-01-01T18:05:28.263 回答
6

如果确实需要在catch块外重新抛出异常,可以使用如下方法:

ExceptionDispatchInfo.Capture(exception).Throw();

ExceptionDispatchInfo类从 .NET Framework 4.5 开始可用。

通常,您不需要使用此方法;相反,您可以 a) 使用 catch 块内的命令重新引发异常throw;,或 b) 将异常包装在另一个异常中。

于 2018-02-20T14:21:49.583 回答
1

您的选择是:

A. 抛出 catch 块:

try
{
    //do stuff
}
catch (Exception ex)
{
    ManageException(ex);
    throw;
}

B. 在处理程序方法中重新抛出:

private void ManageException(Exception ex)
{
    //log or whatever
    throw new Exception("See inner exception", ex);
}

C. 更高级别的处理:

例如在 ASP.NET 中使用 Global.asax 中的 Application_Error 事件处理程序方法。
所有未处理的异常最终都可以在那里处理。

于 2013-01-01T18:35:19.677 回答
0

您只能从 catch 块内重新投掷。想想看;如果您不在 catch 块中,那么您的程序只是崩溃了,或者异常在更高级别被捕获。从 catch 块之外重新抛出是没有意义的。

将您的函数包装在 try/catch 中,并在需要时从 catch 中重新抛出。此外,如果您所做的只是重新投掷,那就没有意义了;只是让异常冒泡。

于 2013-01-01T18:05:54.930 回答
0

你不能。

来自MSDN

可以在 catch 块中使用 throw 语句来重新抛出已被 catch 语句捕获的异常。

如果要保留堆栈跟踪,则必须将其包装InnerException

public static void ManageException(Exception ex, string customErrorMsg, bool displayMessage)
{
   ...
   throw new Exception ("Re-throwing", ex); // You can use your custom Exception object with custom message.
}

的调用者ManageException应该处理ex.InnerException而不是ex.

于 2013-01-01T18:06:02.833 回答