Добавление дополнительной информации в пользовательское исключение - PullRequest
11 голосов
/ 08 сентября 2008

Я создал собственное исключение для очень специфической проблемы, которая может пойти не так. Я получаю данные из другой системы и выдаю исключение, если она бомбит при попытке разобрать эти данные. В свое пользовательское исключение я добавил поле с именем «ResponseData», чтобы я мог точно отслеживать, что мой код не может обработать.

В пользовательских исключениях, таких как это, должны ли эти дополнительные данные ответа входить в исключение "сообщение"? Если он пойдет туда, сообщение может быть огромным. Я как бы этого хочу, потому что я использую Elmah, и вот как я могу получить эти данные.

Так что вопрос тоже: - Как я могу заставить Elmah записывать дополнительную информацию из поля в пользовательском исключении ИЛИ ЖЕ - Должны ли дополнительные сведения об исключении идти в свойство "message"?

Ответы [ 6 ]

11 голосов
/ 01 октября 2008

В пользовательских исключениях, таких как этот, должны ли эти дополнительные ответные данные идти в исключение «сообщение»?

Нет, поскольку Сёрен уже указал . Однако ваш тип исключения может переопределить ToString и разумно добавить туда информацию данных ответа. Это совершенно нормальная практика, за которой следуют многие типы исключений в BCL (библиотеке базовых классов), поэтому вы не будете плыть против течения. Например, взгляните на реализацию System.IO.FileNotFoundException.ToString в SSCLI (Rotor) :

public override String ToString()
{
    String s = GetType().FullName + ": " + Message;

    if (_fileName != null && _fileName.Length != 0)
        s += Environment.NewLine + String.Format(Environment.GetResourceString("IO.FileName_Name"), _fileName);

    if (InnerException != null)
        s = s + " ---> " + InnerException.ToString();

    if (StackTrace != null)
        s += Environment.NewLine + StackTrace;

    try
    {
        if(FusionLog!=null)
        {
            if (s==null)
                s=" ";
            s+=Environment.NewLine;
            s+=Environment.NewLine;
            s+="Fusion log follows: ";
            s+=Environment.NewLine;
            s+=FusionLog;
        }
    }
    catch(SecurityException)
    {

    }
    return s;
}

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

Как я могу заставить Элму записать дополнительные информация из поля в обычае исключение

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

6 голосов
/ 08 сентября 2008

Вы не должны заполнять .Message отладочной информацией, а скорее кратким, полезным фрагментом текста.

http://msdn.microsoft.com/en-us/library/system.exception.message.aspx

Текст сообщения должен полностью описывать ошибку и, по возможности, объяснять, как ее исправить. Значение свойства Message включено в информацию, возвращаемую ToString.

Свойство Message устанавливается только при создании исключения. Если никакое сообщение не было предоставлено конструктору для текущего экземпляра, система предоставляет сообщение по умолчанию, отформатированное с использованием текущей системной культуры.

[..]

Примечания для наследников:

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

Сообщение об ошибке должно быть локализовано.

Данные ответа не относятся к описанию.

Не знаком с elmah, я не могу рассказать вам, как расширить класс Exception при его использовании. Elmah реализует свой собственный подкласс для Exception? Или интерфейс? Можете ли вы сделать это самостоятельно?

5 голосов
/ 01 октября 2008

Класс Exception содержит словарь (по-моему, Data), который вы можете использовать, чтобы связать пользовательские данные с ванильным исключением.

1 голос
/ 08 сентября 2008

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

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

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

Итак, насколько я понимаю ваш вопрос, я думаю, что лучший способ сохранить эту «дополнительную информацию», полученную из другой системы, - это InnerException. Я не знаю Элму, но если она того стоит, она проверит исключения InnerException и сохранит их.

0 голосов
/ 08 сентября 2008

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

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

0 голосов
/ 08 сентября 2008

Я не понимаю вопроса - вы расширяете System.Exception, и вы уже добавили поле Elmah. Вот где оно принадлежит - как публичная собственность самого исключения.

...