Конфигурирование состояния исключения
58C# --- Руководство по C# --- Конфигурирование состояния исключения
В классе Exception доступно множество дополнительных членов (TargetSite, StackTrace, HelpLink и Data), которые могут помочь еще больше уточнить природу проблемы. Давайте рассмотрим возможности каждого из этих членов более подробно.
Свойство TargetSite
Свойство System.Exception.TargetSite позволяет получать различные детали о методе, в котором было сгенерировано данное исключение. Вывод значения свойства TargetSite приводит к отображению возвращаемого значения, имени и параметров выдавшего исключение метода. Вместо простой строки свойство TargetSite возвращает строго типизированный объект System.Reflection.MethodBase. Объект такого типа может применяться для сбора многочисленных деталей, связанных с проблемным методом, а также классом, в котором он содержится.
Свойство StackTrace
Свойство System.Exception.StackTrace позволяет определить последовательность вызовов, которая привела к возникновению исключения. Значение этого свойства никогда самостоятельно не устанавливается — это делается автоматически во время создания исключения.
Строка, возвращаемая из StackTrace, отражает последовательность вызовов, которая привела к выдаче данного исключения. Обратите внимание, что самый нижний номер в этой строке указывает на место возникновения первого вызова в последовательности, а самый верхний — на место, где точно находится породивший проблему член. Очевидно, что такая информация очень полезна при выполнении отладки или просмотре журналов в конкретном приложении, поскольку позволяет прослеживать весь путь, приведший к возникновению ошибки.
Свойство HelpLink
Хотя свойства TargetSite и StackTrace позволяют программистам понять, почему возникло то или иное исключение, пользователям выдаваемая ими информация мало что дает. Как уже показывалось ранее, для получения удобной для человеческого восприятия и потому пригодной для отображения конечному пользователю информации может применяться свойство System.Exception.Message. Кроме него, также может использоваться свойство HelpLink, которое позволяет направить пользователя на конкретный URL-адрес или стандартный справочный файл Windows, где содержатся более детальные сведения о возникшей проблеме.
По умолчанию значением свойства HelpLink является пустая строка. Присваивание этому свойству какого-то более интересного значения должно делаться перед генерацией исключения типа System.Exception.
Свойство Data
Доступное в классе System.Exception свойство Data позволяет заполнять объект исключения соответствующей вспомогательной информацией (например, датой и временем возникновения исключения). Оно возвращает объект, реализующий интерфейс по имени IDictionary, который определен в пространстве имен System.Collections.
Свойство Data очень полезно, так как позволяет формировать специальную информацию об ошибке, не прибегая к созданию совершенно нового класса, который расширяет базовый класс Exception (до выхода версии .NET 2.0 это было единственным возможным вариантом). Однако каким бы полезным ни было свойство Data, разработчики .NET-приложений все равно довольно часто предпочитают создавать строго типизированные классы исключений, в которых специальные данные обрабатываются с помощью строго типизированных свойств.
При таком подходе вызывающий код получает возможность перехватывать конкретный производный от Exception тип, а не углубляться в коллекцию данных в поиске дополнительных деталей.
Давайте рассмотрим пример иллюстрирующий применение вышеуказанных свойств:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
namespace ConsoleApplication1
{
class Program
{
static int MyDel(int x, int y)
{
if (y == 0)
{
// Создаем локальную переменную для получения
// свойства HelpLink
Exception exc = new Exception();
exc.HelpLink = "http://www.professorweb.ru";
// Вставка специальных дополнительных данных
// имеющих отношение к ошибке
exc.Data.Add("Время возникновения: ", DateTime.Now);
exc.Data.Add("Причина: ", "Некорректное значение");
throw exc;
}
return x / y;
}
static void Green()
{
Console.ForegroundColor = ConsoleColor.Green;
}
static void Gray()
{
Console.ForegroundColor = ConsoleColor.Gray;
}
static void Red()
{
Console.ForegroundColor = ConsoleColor.Red;
}
static void Main()
{
try
{
Console.Write("Введите x: ");
int x = int.Parse(Console.ReadLine());
Console.Write("Введите y: ");
int y = int.Parse(Console.ReadLine());
int result = MyDel(x, y);
Console.WriteLine("Результат: " + result);
}
// Обрабатываем общее исключение
catch (Exception ex)
{
Red();
Console.WriteLine("\n*** Error! ***\n--------------\n");
Green();
Console.Write("ОШИБКА: ");
Gray();
Console.Write(ex.Message + "\n\n");
Green();
Console.Write("Метод: ");
Gray();
Console.Write(ex.TargetSite + "\n\n");
Green();
Console.Write("Вывод стека: ");
Gray();
Console.Write(ex.StackTrace + "\n\n");
Green();
Console.Write("Подробности на сайте: ");
Gray();
Console.Write(ex.HelpLink + "\n\n");
Green();
if (ex.Data != null)
{
Console.WriteLine("Сведения: \n");
Gray();
foreach (DictionaryEntry d in ex.Data)
Console.WriteLine("-> {0} {1}", d.Key, d.Value);
Console.WriteLine("\n\n");
}
Gray();
Main();
}
Console.ReadLine();
}
}
}