简体   繁体   中英

Changing Exception type to base class

I have two projects. In one of them I use MailKit and it is responsible for all kinds of email. Here I could get SmtpCommandExceptions or SmtpProtocolExceptions that are derived of CommandException which is derived of the normal System.Exception . I want to give the exception to the other project without binding the complete MailKit into the other project. So I thought about getting the additional properties into strings, putting them together and send everything else back.

Is there any way of extracting the exception out of the derived class and throw away all additional methods, properties, and so on?

The typical way to deal with this kind of problem is to wrap the exception in a custom exception class:

public class MyWrappedException : Exception
{
    public string MyProperty { get; }

    public MyWrappedException(string message, string myProperty, Exception innerException)
        : base(message, innerException)
    {
        MyProperty = myProperty;
    }
}

Called like:

  try
  {
      DoSomething();
  }
  catch(InvalidOperationException ex)
  {
      throw new MyWrappedException("Oups", "tried doing X", ex);
  }

This keeps the all the original exception information, but most of it will not be visible unless you use a debugger or it is included when converting to a string. You can select what properties you want to include in the wrapper. This lets you catch your wrapped exception without an direct dependency on mailkit.

As far as stacktrace is concerned, you could just pass base Exception. But if you want more information, specific to some exception class, I can think of one solution.

For example, create a class like:

public class ExceptionInfo
{
    public string Message {get;set;}
    public int SomeValue {get;set;}
    public double SomeOtherValue {get;set;}
    
    public readonly Exception OriginalException;
    
    public ExceptionInfo(Exception originalEx)
    {
        OriginalException = originalEx;
    }
}

Now, when you catch specific exception, you can serialize it like so:

catch(SmtpCommandException ex)
{
   ExceptionInfo info = ex.MakeExceptionInfo(); //this should be some helper method
   SendException(info);
}

Now, the solution is to create a helper method for each kind of exception, or just some generic method that would create your ErrorInfo with common exception values that you want to have. For example:

public static ExceptionInfo MakeExceptionInfo(this SmptCommandException ex)
{
    ExceptionInfo result = new ExceptionInfo(ex);
    result.SomeValue = ex.SomevalueFromOriginalException;

    return result;
}

Next, when you have your ExceptionInfo class you can send it to other parts of your application.

Firstly I thought that you could use serialization (for example json), but I thing that this solution is much more clearer. But requires some coding. Maybe you will come up with solution that combines my idea with json.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM