Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Log all exception information for any kind of exception

I'm developing with 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 on my log file I have found this:

Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.

When I wrote 'See 'EntityValidationErrors' property for more details.', I'm only showing an example where I haven't log an important property.

There are a lot of kind of exceptions; but with my method I'm not logging all the relevant information because there could be properties like 'EntityValidationErrors' that I don't log.

When I pass the exception to log it I don't know what properties it has, and I don't know how to log each property it has.

Do you know a method to log an exception completely? My code doesn't long exceptions with an EntityValidationErrors property or any other important property.

I'm doing the logging with log4net.

like image 517
VansFannel Avatar asked Apr 22 '15 12:04

VansFannel


People also ask

How do I log an exception?

To log a handled exception Create the method that will generate the exception information. Use a Try...Catch block to catch the exception. Put the code that could generate an exception in the Try block. Uncomment the Dim and MsgBox lines to cause a NullReferenceException exception.

Should all exceptions be logged?

Definitely not. You should find the correct place to handle the exception (actually do something, like catch-and-not-rethrow), and then log it. You can and should include the entire stack trace of course, but following your suggestion would litter the code with try-catch blocks.

How do you log an entire exception in Python?

To log an exception in Python we can use logging module and through that we can log the error. Logging an exception in python with an error can be done in the logging. exception() method. This function logs a message with level ERROR on this logger.

Should you log before throwing exception?

Log it when you handle it So, better only log the exception when you handle it. Like in the following code snippet. The doSomething method throws the exception. The doMore method just specifies it because the developer doesn't have enough information to handle it.


1 Answers

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

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

If this does work, however, you will still be missing the EntityValidationErrors.

Another method, which I used recently is to just explicitly trap 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 the Exception.Data dictionary entries, you can add those 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 for properties for Custom exception classes just as the EntityValidationErrors, I would just trap and parse those where they occur. Otherwise you would have to override ToString() on every exception type or use some reflection hackery to enumerate all the properties which would significantly clutter the logs with properties you dont care about.

like image 91
Brad C Avatar answered Nov 03 '22 04:11

Brad C