2015-04-22 2 views
3

Я разрабатываю C#, ASP.NET MVC Web Api, Entity Framework и .NET Framework 4.0.Записывать всю информацию об исключениях для любого исключения

У меня есть этот код для входа исключение:

public void LogCompleteException(
    string controllerName, 
    string actionName, 
    Exception exception) 
{ 
    string exceptionMessage = string.Empty; 

    Exception e = exception; 
    if (e.InnerException == null) 
     e = null; 
    else 
     while (e.InnerException != null) e = e.InnerException; 

    if (e == null) 
     exceptionMessage = exception.Message; 
    else 
     exceptionMessage = string.Format("{0}\n\rInnerException: {1}", exception.Message, e.Message); 

    _logger.ErrorFormat(
     LogTextFormatString, 
     ExceptionText, 
     controllerName, 
     actionName, 
     exceptionMessage); 
} 

Но на мой лог-файл я нашел это:

Проверка не для одного или нескольких объектов. Дополнительную информацию см. В разделе Свойство EntityValidationErrors.

Когда я писал «свойство для получения более подробной информации.„“Увидеть» EntityValidationErrors, я только показываю пример, где я не войти важное свойство.

Существует множество исключений; но с моим методом я не регистрирую всю соответствующую информацию, потому что могут существовать такие свойства, как «EntityValidationErrors», которые я не регистрирую.

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

Знаете ли вы, что метод полностью регистрирует исключение? Мой код не содержит длинных исключений с собственностью EntityValidationErrors или любым другим важным свойством.

Я веду журнал с log4net.

+0

Я предполагаю, что регистрация осуществляется через log4net? – br4d

+0

Да, я регистрирую log4net. – VansFannel

+0

Почему бы не использовать exception.ToString()? –

ответ

3

Поскольку внутреннее исключение является само по себе исключение, возможно, вы можете просто рекурсию и использовать метод у вас уже есть:

if (e.InnerException != null) 
{ 
    LogCompleteException(controllerName, actionName, e.InnerException); 
} 

Если это работа, однако, по-прежнему отсутствует в EntityValidationErrors.

Другой метод, который я использовал в последнее время, это просто явно ловушки и войти исключение, где это происходит:

try 
{ 
    db.Add(something); 
    db.SaveChanges(); 
} 
catch (DbEntityValidationException ex) 
{ 
    StringBuilder sb = new StringBuilder(); 

    // collect some extra info about the exception before logging 
    foreach (var eve in ex.EntityValidationErrors) 
    { 
     sb.AppendLine(String.Format("Entity of type \"{0}\" in state \"{1}\" has the following validation errors:", eve.Entry.Entity.GetType().Name, eve.Entry.State)); 
     foreach (var ve in eve.ValidationErrors) 
     { 
      sb.AppendLine(String.Format("Property: \"{0}\", Error: \"{1}\"", ve.PropertyName, ve.ErrorMessage)); 
     } 
    } 

    logger.Error("There was an error while trying to parse and save something!\n" + sb.ToString(), ex); 
} 

Если вы хотите словарные Exception.Data, вы можете добавить их, а также:

foreach (DictionaryEntry entry in ex.Data) 
{ 
    // you will want to use a StringBuilder instead of concatenating strings if you do this 
    exceptionMessage = exceptionMessage + string.Format("Exception.Data[{0}]: {1}", entry.Key, entry.Value); 
} 

Что касается свойств для пользовательских классов исключений, таких как EntityValidationErrors, я просто поймаю и проанализирую те, где они происходят. В противном случае вам придется переопределить ToString() для каждого типа исключений или использовать хакерство с отражением, чтобы перечислять все свойства, которые значительно помешали бы журналам со свойствами, которые вам не нужны.

+0

Я думаю, что я не очень хорошо объяснил свой вопрос. Когда я написал свойство «См.« EntityValidationErrors »для получения более подробной информации». Я показываю пример, что я не регистрирую важное свойство. Есть много исключений, и с моим методом я не регистрирую всю эту информацию. – VansFannel

+0

Можете ли вы привести больше примеров «важных свойств»? Подавляющее большинство исключений хранит эти данные в [Исключительный словарь данных] (https://msdn.microsoft.com/en-us/library/system.exception.data%28v=vs.110%29.aspx). Хотя есть исключения (например, EntityValidationErrrors), и вам нужно будет использовать отражение, чтобы перечислять все свойства исключения или явно проверять их заранее. Лучшая вещь для этих выбросов - обращаться с ними при броске по мере необходимости, например, в моем примере кода IMO. – br4d

+0

Я не могу дать вам больше примеров «свойств импорта», потому что я не знаю, какое исключение я должен был бы зарегистрировать. Вот почему я попросил об исключении журнала полностью, потому что я хочу регистрировать любое свойство с информацией. Кстати, я регистрирую самое внутреннее 'IneerException' с помощью этой строки' while (e.InnerException! = Null) e = e.InnerException; '. – VansFannel

0

Вы можете использовать elmah и log4net appender. Журналы Elmah захватывают все исключения и могут записывать их в экземпляр log4net.

Смежные вопросы