Когда лучше не создавать пользовательские исключения? - PullRequest
2 голосов
/ 28 декабря 2010

Я сделал компонент, который выбрасывает исключение.Я думаю, следует ли мне придерживаться стандарта throw new Exception или создавать особые исключения.

Я также считаю, что пользовательское исключение не является привлекательным, когда оно вызывает исключение из Remoting или WCF.если я использую стандартное исключение, вызывающий может получить исключение, если я создал пользовательское исключение, вызывающий не сможет получить конкретное исключение, если только сборка компонента не будет развернута на клиенте;тем не менее, клиент может получить исключение из определенных пользователем исключений, если один поймает определенное пользователем исключение из Remoting и WCF и повторно выбрасывает его как стандартное исключение, что, в свою очередь, противоречит цели определяемого пользователем исключения.

Когда добавление пользовательского исключения не так полезно?

[РЕДАКТИРОВАТЬ]

Делиться своими мыслями, я думаю, что пользовательское исключение является обязательным (хотя бы одно) на компоненте, поэтому при модульном тестировании собственного компонента вы не получите ложных срабатываний.

Это приводит к ложным срабатываниям:

[Test]
public void Tag_is_missing()
{

    string message = "";

    try
    {
        // Arrange  
            // this will fail on *nix systems       
        MyComponentHelper.ParseXml("C:\A.XML");
    }
    catch(Exception ex)
    {
        // Act
        message = ex.InnerException.Message;
    }


    // Assert
    // How can we be sure that the word "not found" error is from 
    // xml parsing or if from file loading? Doing Pokemon exception handling
    // will lead to ambiguities
    Assert.IsTrue(message.Contains("not found"));

}

Если вы не сделали свое собственное исключение, ваш модульный тест может получить ложные срабатывания, строка «not found» может быть из вашего компонента или из других подсистем вашего компонента.Итак, мой случай, когда нужно создать пользовательское исключение.

Это не приведет к ложным срабатываниям:

[Test]
public void Tag_is_missing()
{

    string message = "";

    try
    {
        // Arrange     
        // this will fail on *nix systems        
        MyComponentHelper.ParseXml("C:\A.XML");
    }
    catch(XmlParsingException ex)
    {
        // Act
        message = ex.InnerException.Message;

        // Assert
        // And now we are more sure that the error didn't come from
        // program subsystem; in particular, file subsystem.
        Assert.IsTrue(message.Contains("not found"));
    }


}

Остается задуматься над тем, когда нужно создавать очень специфичные пользовательские исключения.Сейчас я сначала остановлюсь на наличии только одного пользовательского исключения для моего компонента, модульное тестирование не должно давать ложных срабатываний.

Ответы [ 3 ]

2 голосов
/ 28 декабря 2010

Используйте пользовательские исключения, когда вы чувствуете, что стандартные исключения (предоставляемые .NET) не дают достаточной информации об условии исключения.В этом пользовательском исключении можно указать свойства, которые предоставляют больше информации об исключении, чем просто строка сообщения.

Настраиваемое исключение является только оболочкой для системного исключения.Исходная информация об исключении находится в свойстве InnerException настраиваемого исключения.

Класс исключения можно оформить следующим образом:


public class NewException : BaseException, ISerializable
{
    public NewException()
    {
        // Add implementation.
    }
    public NewException(string message)
    {
        // Add implementation.
    }
    public NewException(string message, Exception inner)
    {
        // Add implementation.
    }

    // This constructor is needed for serialization.
   protected NewException(SerializationInfo info, StreamingContext context)
   {
        // Add implementation.
   }
}

При создании пользовательского исключения используйте:


try
{
   .....
}
catch(ArgumentNullException argumentNullException)
{
   throw new NewException("This is a custom exception message", argumentNullException);
}

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

Для получения дополнительной информации см .:

0 голосов
/ 28 декабря 2010

Trapping for Exception очень универсален и может маскировать другие непредвиденные ошибки (как вы уже упоминали) в других областях вашего компонента. Использование свойств или других сообщений является опцией.

Тем не менее, подход, который я нашел, работает лучше всего, это выбросить одно из стандартных исключений, которое является подклассом Exception (например, ArgumentOutOfRangeException); если они недостаточно точны, и вам нужно что-то бросить, создайте подкласс и бросьте это.

Также имейте в виду, что исключения предназначены для исключительных случаев. Имеет ли смысл генерировать исключение, или вам лучше обслужить возвращение некоторого значения (я не имею в виду код ошибки)?

0 голосов
/ 28 декабря 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...