未捕获特定于应用程序的异常包装 "MongoDuplicateKeyException"

Application specific exception wrapping "MongoDuplicateKeyException" not catch'ed

出于需要创建了应用程序异常,它包装了一个 MongoDuplicateKeyException 并像下面那样抛出该异常

Public class AppException : Exception
{
  // all constructor implementation 

  public int ErrorCode { get; set; }
  public string AppMessage { get; set; }
}

在方法中捕获并抛出异常

public async Task<Response> Method1(parameter ...)
{
  try
   {
      //some insert/update operation to DB 
      return <instance of Response>;
   }
  catch(MongoduplicateKeyException ex)
  {
    var exception = new AppException(ex.Message, ex)
    {
      ErrorCode = 22,
      AppMessage = "some message",
    };

    throw exception;
  }
}

上面调用Method1()的方法

try
{
  //some other operation
  var response = await Method1();
}
catch(AppException ex)
{
  SomeOtherLoggingMethod(ex, other parameter);
}
catch(Exception ex)
{
  SomeMethod(ex, other parameter);
}

令人惊讶的是,即使我从 Method1() 中抛出 AppExceptioncatch(AppException ex) 捕获块也从未被捕获。它总是捕获通用 catch 块 catch(Exception ex).

经过调试,发现在catch(Exception ex)catch块中异常类型ex.GetType()实际上是一个WriteConcernException类型(MongoduplicateKeyException : WriteConcernException)。

所以本质上,特定的 catch 块未命中导致异常类型不是 AppException 而是 WriteConcernException But

不知道为什么会这样?我在这里遗漏了一些明显的东西吗?请提出建议。

您在调试中找到了答案。 catch(AppException ex) 块未执行,因为 public async Task<Response> Method1 不抛出 AppException,而是抛出 WriteConcernException。

The API shows WriteConcernException 是 DuplicateKeyException 的超类,因此未命中 Method1 中的 catch 块并且异常冒泡到调用方中的第二个 catch 块。

因此,如果您更新代码以捕获适当的异常,它应该会按预期工作。

public async Task<Response> Method1(parameter ...)
{
    try
    {
        //some insert/update operation to DB
        return <instance of Response>;
    }
    catch (MongoServerException mse)
    ...