Всемогущий, Google, найди мне чего-нибудь!

пятница, 2 июля 2010 г.

Получить все сообщения из объекта класса Exception.

Итак, после долгого перерыва решил написать новую коротенькую, но полезную статью.

В процессе разработки у каждого программиста возникают исключения (Exceptions), сообщения которых не могут дать полной картины о них. Сегодня я покажу маленькие, но очень полезные методы-расширения для класса Exception и всех его наследников. Методы буду выбирать сообщения из всех внутренних исключений объекта класса Exception, чтобы получить полную картину об исключении.

Итак, начнем. Для начала необходимо написать статический класс, который будет хранить эти методы. Выглядеть он будет очень просто:
namespace System
{
    /// <summary>
    /// Holds extension methods for <see cref="Exception"/> class.
    /// </summary>
    public static class ExceptionExtenstion
    {
        /// <summary>
        /// Returns all messages from non-null inner exception of current 
        /// <see cref="Exception"/> object terminated by given separator.
        /// </summary>
        /// <param name="source">
        ///     Current <see cref="Exception"/> object.
        /// </param>
        /// <param name="separator">
        ///     String separator for exception messages.
        /// </param>
        /// <returns>
        ///     All messages of non-null inner exceptions in one string.
        /// </returns>
        public static string InnerMessage(this Exception source, string separator)
        {
            return InnerMessage(source, string.Empty, separator);
        }

        /// <summary>
        /// Returns all messages from non-null inner exception of current 
        /// <see cref="Exception"/> object terminated by given separator.
        /// </summary>
        /// <param name="source">
        ///     Current <see cref="Exception"/> object.
        /// </param>
        /// <param name="message">
        ///     String message to start selecting inner exception messages with.
        /// </param>
        /// <param name="separator">
        ///     String separator for exception messages.
        /// </param>
        /// <returns>
        ///     All messages of non-null inner exceptions in one string.
        /// </returns>
        public static string InnerMessage(this Exception source, string message, string separator)
        {
            string fullMessage = string.Format("{0}{1}{2}", message, source.Message, separator);

            if (source.InnerException != null)
            {
                fullMessage = InnerMessage(source.InnerException, fullMessage, separator);
            }

            return fullMessage;
        }
    }
}

Вуаля. Теперь, если необходимо выбрать все сообщения, чтобы получить полную картину об исключении - пользуемся сими двумя не замысловатыми функциями.

А вот как я использовал в одном из проектов при работе с базой данных (упрощенная версия):
try
{
 this.BeginTransaction();
 
 /* Тут идет работа с базой данных */ 

 this.Commit(); 
}
catch(Exception exception)
{
 this.Rollback();
 string exceptionMessage = exception.InnerMessage("Error occurs while working with database. Error stack: ", ". ");
 Log.Write(exceptionMessage);
 throw;
}
Если надо скопировать код, то не смотрим на то, как нам отобразил HighLighter, а тыкаем на "View plain" и копируем оттуда.

2 комментария:

tayg комментирует...

Было б неплохо привести пример использования.

Unknown комментирует...

Секундочку, сейчас поправим. :)