#c# #.net #exception #exception-handling
#c# #.net #исключение #обработка исключений
Вопрос:
Ситуация, когда метод пытается зарегистрировать пользовательское исключение (пользовательский класс исключений в качестве примера кода), вызывает проблему:
[Serializable]
public class CustomException : Exception
{
public CustomException() { }
public CustomException(string message) : base(message) { }
public CustomException(string message, Exception inner) : base(message, inner) { }
protected CustomException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}
Создание исключения:
CustomException ex = new CustomException("Here is a new custom exception! ");
LogError(ex);
Метод регистрации исключений (пользовательских и других!):
public static void LogError(Exception ex)
{
//Saving exception messages, inner exceptions etc
//...
}
В этом случае ex.Stacktrace пользовательского исключения имеет значение null при его регистрации!
Я полагаю, причина в том, что метод ведения журнала (который пытается быть методом общего назначения) принимает объект исключения в качестве параметра, а не CustomException (?). Каков правильный способ создания метода ведения журнала, поскольку перегрузка его различными типами исключений кажется немного нелогичной?
Комментарии:
1.но
Exception
имеетStackTrace
свойство, которое не расширяетсяCustomException
msdn.microsoft.com/en-us/library/system.exception.aspx2. @Jodrell: О чем ты говоришь? StackTrace отлично работает для всех исключений
3. @jgauffin: вот что я имею в виду, все исключения
StackTrace
унаследованы отException
so, утверждение «Я полагаю, причина в том, что метод ведения журнала (который пытается быть методом общего назначения) принимает объект исключения в качестве параметра, а не CustomException (?).» Должно быть, неверно.4. @Jodrell: ах, хорошо. Я запутался в
its not extended
Ответ №1:
Я полагаю, причина в том, что метод ведения журнала (который пытается быть методом общего назначения) принимает объект исключения в качестве параметра, а не CustomException (?)
Неверно. Это значение равно нулю, поскольку вы на самом деле не создавали исключение, а просто создали его.
Трассировка стека генерируется по мере продвижения исключения вверх по стеку вызовов. Выбрасывание исключения тем же методом, которым вы его перехватываете, создаст только один элемент трассировки стека.
Ответ №2:
Вы можете использовать:
public static void LogError<T>(T exception)
{
// Serialize the exception here and write to log
}
Обратите внимание, что вы можете просто использовать любой объект здесь в сочетании с удобочитаемым форматом сериализации (т. Е. в формате Json). Затем вы можете просто зарегистрировать сериализованное представление объекта, где все общедоступные поля / свойства будут сохранены.
Обратите внимание, что вам также понадобится throw / catch для построения stacktrace для вас.
Комментарии:
1. Пожалуйста, объясните, почему универсальный метод будет лучше, чем тот, который используется
Exception
в качестве аргумента. Я не понимаю.2. Я не хотел ограничивать регистратор только
Exception
объектами. Вы можете возразить, что я мог бы использовать ‘object’ в качестве аргумента, но мне нравится оставаться строго типизированным при использовании сериализации / десериализации.3. Я не вижу никаких преимуществ наличия строго типизированных объектов во время сериализации, поскольку большинство сериализаторов
object
тоже работают.
Ответ №3:
Создайте CustomException
экземпляр перед его регистрацией. Среда выполнения заполнит информацию о трассировке стека
Ответ №4:
- Регистрируйте исключения в блоке catch
- Проверьте уровень ведения журнала и регистрируйте только сообщение или полную информацию об исключении.
Например, мы используем методы расширения для TraceSource для регистрации исключений:
public static void TraceException(this TraceSource traceSource, Exception ex)
{
traceSource.TraceException(string.Empty, ex);
}
public static void TraceException(this TraceSource traceSource, string comment, Exception ex)
{
if (!string.IsNullOrWhiteSpace(comment))
comment = "rn";
traceSource.TraceEvent(TraceEventType.Error, (int)TraceEventType.Error,
comment "ExceptionType: {0} rn ExceptionMessage: {1}", ex.GetType(), ex.Message);
if (traceSource.Switch.Level == SourceLevels.Verbose ||
traceSource.Switch.Level == SourceLevels.All)
{
traceSource.TraceEvent(TraceEventType.Verbose, 0, ex.ToString());
}
}
Использование:
catch(Exception ex)
{
_log.TraceException(ex);
}