Log all exception information for any exception

I am developing C #, ASP.NET MVC Web Api, Entity Framework and .NET Framework 4.0.

I have this code to log an exception:

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);
}

      

But in my log file I found this:

Failed to check for one or more objects. See PropertyValidationErrors for more details.

When I wrote 'See' EntityValidationErrors 'for more details.', I am only showing an example where I am not registering an important property.

There are many exceptions; but with my method I am not logging all the relevant information because there might be properties like "EntityValidationErrors" that I am not logging.

When I pass an exception to register, I don't know what properties it has, and I don't know how to register every property it has.

Did you know that the method completely logs the exception? My code does not contain long property exceptions EntityValidationErrors

or any other important property.

I am logging with log4net.

+3


source to share


2 answers


Since the inner exception is the exception itself, perhaps you can just repeat and reuse the method you already have:

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

      

If it still works, you will still be missing the EntityValidationErrors.

Another technique I used recently is to just block explicitly and log the exception where it occurs:



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);
}

      

If you want to use the dictionary of the word Exception.Data, you can add them as well:

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);
}

      

As far as properties for custom exception classes like EntityValidationErrors go, I'll just catch and analyze where they happen. Otherwise, you will have to override ToString () for each type of exception, or use reflection hacking to list all the properties that would significantly interfere with logs with properties you don't need.

+3


source


you can use elmah and log4net appender . Elmah logs capture all exceptions and can write them to the log4net instance.



0


source







All Articles