Обработка и описание исключений в библиотеке классов
От: Аноним  
Дата: 21.09.11 14:18
Оценка:
Хотел бы узнать ваше мнение, как правильно обрабатывать исключения в библиотеке классов, и о каких исключениях сообщать в XML-комментариях.

Давайте рассмотрим надуманный пример:
        /// <summary>
        /// Создаёт экземпляр класса <see cref="MyObject"/> на основе информации из файла.
        /// </summary>
        /// <param name="pathToFile">Путь к файлу, который содержит информацию об объекте.</param>
        /// <returns>Экземпляр класса <see cref="MyObject"/>, созданный на основе информации из файла.</returns>
        /// <exception cref="System.ArgumentException">Значение параметра <paramref name="pathToFile"/> равно <see langword="null"/> или имеет нулевую длину.</exception>
        /// <exception cref="System.FormatException">Неправильный формат данных файла.</exception>
        public MyObject CreateMyObjectFromFile<TObject>(string pathToFile)
        {
            if (string.IsNullOrEmpty(pathToFile))
            {
                throw new ArgumentException(..., "pathToFile");
            }

            string fileContent;

            using (FileStream fStream = new FileStream(pathToFile, FileMode.Open))
            using (StreamReader sReader = new StreamReader(fStream))
            {
                fileContent = sReader.ReadToEnd();
            }

            // Проверяем правильность данных.
            if (...)
            {
                throw new FormatException(...);
            }

            // Вычисляем MD5 хэш-значение для одного из параметров объекта.
            using (HashAlgorithm hashProvider = new MD5CryptoServiceProvider())
            {
                StringBuilder hashBuilder = new StringBuilder();
                ...
            }

            // Создаём и возвращаем экземпляр класса.
            MyObject myObject = ...;

            return myObject;
        }



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

— Оставить как есть — это приемлемый вариант.
— Оставить как есть, но в XML-комментарии добавить все возможные исключения сторонних классов, просто скопировав их описание из документации.
— Сделать обёртку try-catch-finally над каждым потенциально-опасным вызовом. В catch сделать повторную генерацию исключения с пояснением ошибки и задать начальное исключение. В XML-комментариях указать все эти возможные исключения:
        /// <summary>
        /// Создаёт экземпляр класса <see cref="MyObject"/> на основе информации из файла.
        /// </summary>
        /// <param name="pathToFile">Путь к файлу, который содержит информацию об объекте.</param>
        /// <returns>Экземпляр класса <see cref="MyObject"/>, созданный на основе информации из файла.</returns>
        /// <exception cref="System.ArgumentException">Значение параметра <paramref name="pathToFile"/> равно <see langword="null"/> или имеет нулевую длину.</exception>
        /// <exception cref="System.FormatException">Неправильный формат данных файла.</exception>
        /// <exception cref="System.Security.SecurityException">У вызывающего объекта отсутствует необходимое разрешение доступа к файлу.</exception>
        /// <exception cref="System.IO.IOException">Произошла ошибка ввода-вывода, при попытки считать данные файла.</exception>
        /// <exception cref="System.InvalidOperationException">Ошибка при вычисления MD5 хэш-значение, так как политика FIPS-совместимого алгоритма не задействована.</exception>
        public MyObject CreateMyObjectFromFile<TObject>(string pathToFile)
        {
            if (string.IsNullOrEmpty(pathToFile))
            {
                throw new ArgumentException(..., "pathToFile");
            }

            string fileContent;
            FileStream fStream;
            StreamReader sReader;

            try
            {
                fStream = new FileStream(pathToFile, FileMode.Open);
                sReader = new StreamReader(fStream);

                fileContent = sReader.ReadToEnd();
            }
            catch (SecurityException ex)
            {
                throw new SecurityException("Не удалось получить доступ к файлу, который хранить информацию об объекте.", ex);
            }
            catch (IOException ex)
            {
                throw new IOException("Не удалось считать данные из файла, который хранить информацию об объекте.", ex);
            }
            finally
            {
                if (sReader != null)
                {
                    sReader.Dispose();
                }

                if (fStream != null)
                {
                    fStream.Dispose();
                }
            }

            // Проверяем правильность данных.
            if (...)
            {
                throw new FormatException(...);
            }

            HashAlgorithm hashProvider;

            try
            {
                // Вычисляем MD5 хэш-значение для одного из параметров объекта.
                hashProvider = new MD5CryptoServiceProvider();

                StringBuilder hashBuilder = new StringBuilder();
                ...
            }
            catch (InvalidOperationException ex)
            {
                throw new InvalidOperationException("Не удалось вычислить MD5 хэш-значение для одного из параметров объекта.", ex);
            }
            finally
            {
                if (hashProvider != null)
                {
                    hashProvider.Dispose();
                }
            }

            // Создаём и возвращаем экземпляр класса.
            MyObject myObject = ...;

            return myObject;
        }
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.