Search code examples
c#mongodbmongodb-.net-driver

Application specific exception wrapping "MongoDuplicateKeyException" not catch'ed


Out of need have created application exception which wraps a MongoDuplicateKeyException and throwing that exception like below

Public class AppException : Exception
{
  // all constructor implementation 

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

In method catching and throwing exception

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;
  }
}

Method that calls Method1() above

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

Surprisingly the catch(AppException ex) catch block never gets catched even though am throwing an AppException from Method1(). It always catch the generic catch block catch(Exception ex).

After debugging, found that in catch(Exception ex) catch block the exception type ex.GetType() is actually a WriteConcernException type (MongoduplicateKeyException : WriteConcernException).

So essentially that specific catch block not hitting cause the exception type is not AppException rather WriteConcernException But

Not sure why is it so? am I missing something obvious here? Please suggest.


Solution

  • You found the answer while debugging. The catch(AppException ex) block is not executed because public async Task<Response> Method1 does not throw an AppException it throws a WriteConcernException.

    The API shows a WriteConcernException is the superclass of DuplicateKeyException so the catch block in Method1 is not hit and the exception bubbles up to the 2nd catch block in the caller.

    So if you update your code to catch the appropriate exception it should work as you intend.

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