【问题标题】:Custom exception- Try catch - in c#自定义异常 - Try catch - 在 C# 中
【发布时间】:2017-01-05 00:44:29
【问题描述】:

允许使用自定义异常,可以像下面这样抛出异常。

  try
{
    int foo = int.Parse(token);
}
catch (FormatException ex)
{
    //Assuming you added this constructor
    throw new ParserException(
      $"Failed to read {token} as number.", 
      FileName, 
      LineNumber, 
      ex);
}

但是在正常的 try catch 块中,它说,抛出异常将清除堆栈跟踪。

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

那么在自定义异常中,如何在不清除堆栈跟踪的情况下使用 throw 异常?

【问题讨论】:

  • 您将try block(FormatException)中的原始异常作为ParserException构造函数中的内部异常传递,因此您可以通过InnerException成员获取原始堆栈跟踪
  • 内部异常怎么说?
  • 根据您提到的链接中的代码。但是,此链接不提供您使用的构造函数的完整实现。只需修改这个 ParserException(string msg, Exception inner) : base(msg, inner) { }。因此,在捕获您的自定义 excexption 时,您可以将原始堆栈作为 YourCustomExceptionObject.InnerException.StackTrace
  • 只说throw 而不是throw ex

标签: c# .net exception-handling


【解决方案1】:

有几种方法可以做到这一点。

正如这个链接In C#, how can I rethrow InnerException without losing stack trace?中提到的,你可以使用ExceptionDispatchInfo Class 代码类似于

try
{
    task.Wait();
}
catch(AggregateException ex)
{
    ExceptionDispatchInfo.Capture(ex.InnerException).Throw();
}

另一种方法是让您的处理程序返回一个布尔值,无论是否处理了异常,因此您可以在 catch 子句中使用它:

catch (Exception ex) {
  if (!HandleException(ex)) {
    throw;
  }
}

HandleException 是您的自定义异常处理程序。从此链接获得:How to throw exception without resetting stack trace?

【讨论】:

    【解决方案2】:

    每当您将throw 与异常对象一起使用时,它都会在该点填充堆栈跟踪。 (与 Java 相比,Java 在构造异常时填充堆栈跟踪。)

    如果您使用throw 而不使用异常对象,您只能在catch 子句中执行此操作,则捕获的异常对象将被重新抛出而不进行更改。

    【讨论】:

      猜你喜欢
      • 2021-09-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-03
      • 1970-01-01
      • 2019-10-21
      • 2012-05-04
      • 2013-12-05
      相关资源
      最近更新 更多