Как сериализовать исключение в классе библиотеки Project? - PullRequest
1 голос
/ 07 июня 2019

Я хочу использовать библиотеку PhoneNumbers от Google в своем плагине CRM Dynamics.

Мой плагин пытается разобрать номер телефона. При выполнении я получил следующее исполнение:

System.Runtime.Serialization.SerializationException: тип не разрешен для члена PhoneNumbers.NumberParseException, aug.R2BCore.Crm.Plugins

в классе исключений отсутствует атрибут Serialized, я его добавил.

Вот код класса исключения:


namespace PhoneNumbers
{
    public enum ErrorType
    {
        INVALID_COUNTRY_CODE,
        // This generally indicates the string passed in had less than 3 digits in it. More
        // specifically, the number failed to match the regular expression VALID_PHONE_NUMBER in
        // PhoneNumberUtil.java.
        NOT_A_NUMBER,
        // This indicates the string started with an international dialing prefix, but after this was
        // stripped from the number, had less digits than any valid phone number (including country
        // code) could have.
        TOO_SHORT_AFTER_IDD,
        // This indicates the string, after any country code has been stripped, had less digits than any
        // valid phone number could have.
        TOO_SHORT_NSN,
        // This indicates the string had more digits than any valid phone number could have.
        TOO_LONG
    }

    [Serializable] // added 
    public class NumberParseException : Exception
    {
        public readonly ErrorType ErrorType;

        public NumberParseException(ErrorType errorType, string message) :
            base(message)
        {
            ErrorType = errorType;
        }
    }
}

1 Ответ

0 голосов
/ 08 июня 2019

Плагин работает в отдельном контексте домена приложения. Когда вы выбрасываете исключение, оно затем передается в SandboxExecutionWorkerProcess, который выполняется в другом домене приложения, чем ваш плагин, и вы не знаете, какой у вас тип исключения. Поэтому независимо от того, как вы сериализуете исключение, тип должен быть десериализуемым с другой стороны.

Я бы порекомендовал следующий подход (упаковка исключений):

public abstract class BasePlugin : IPlugin {
  protected abstract DoExecute(IServiceProvider serviceProvider);
  public void Execute(IServiceProvider serviceProvider) {
    try { 
      this.DoExecute(serviceProvider); 
    } catch (Exception e) {
      throw new InvalidPluginExecutionException(e.ToString());
    }
  }
}

Если у вас есть фиксированный набор пользовательских типов исключений, вы можете улучшить этот код для обработки только тех. Также имейте в виду, что, делая это, вы предоставляете трассировку стека пользователям CRM - хорошо, если вы разрабатываете плагин только для своей компании, но если вы являетесь независимым разработчиком ПО, вам следует подумать о его скрытии.

...