What is the best practice for capturing all inner exception details?

26,888

Solution 1

Have you tried just using ex.ToString()? It gives most (if not all) of the data you need to diagnose - including the message details, stack trace, and inner exceptions:

From MSDN:

ToString returns a representation of the current exception that is intended to be understood by humans. Where the exception contains culture-sensitive data, the string representation returned by ToString is required to take into account the current system culture. Although there are no exact requirements for the format of the returned string, it should attempt to reflect the value of the object as perceived by the user. The default implementation of ToString obtains the name of the class that threw the current exception, the message, the result of calling ToString on the inner exception, and the result of calling Environment.StackTrace. If any of these members is null, its value is not included in the returned string.

Solution 2

I have this extension method which suits my purposes just fine.

public static class ExceptionExtensions {
    public static string ToMessageAndCompleteStacktrace(this Exception exception) {
        Exception e = exception;
        StringBuilder s = new StringBuilder();
        while (e != null) {
            s.AppendLine("Exception type: " + e.GetType().FullName);
            s.AppendLine("Message       : " + e.Message);
            s.AppendLine("Stacktrace:");
            s.AppendLine(e.StackTrace);
            s.AppendLine();
            e = e.InnerException;
        }
        return s.ToString();
    }
}

And use it like this:

using SomeNameSpaceWhereYouStoreExtensionMethods;
try {
    // Some code that throws an exception
}
catch(Exception ex) {
    Console.WriteLine(ex.ToMessageAndCompleteStacktrace());
}

Update

Since I'm receiving upvotes for this answer I want to add that I stopped using this extension method, and now I'm just using exception.ToString(). It gives more information. So please, stop using this method, and just use .ToString(). See the answer above.

Share:
26,888

Related videos on Youtube

CodeWarrior
Author by

CodeWarrior

Updated on April 16, 2020

Comments

  • CodeWarrior
    CodeWarrior about 4 years

    What is the best practice for logging complete exception details including all possible inner exceptions?

    Currently, I use the following code:

    try
    {
        //some code that throws an exception
    }
    catch(Exception ex)
    {
        do
        {
            Console.WriteLine(ex.Message+ex.StackTrace);
            ex=ex.InnerException;
        }while(ex!=null)
    }
    

    Are there any scenarios where this code may fail?

    • Matthew Watson
      Matthew Watson over 10 years
      Yes, you might want to also handle AggregateException since they have an InnerExceptions property which you will otherwise miss.
    • Dustin Kingen
      Dustin Kingen over 10 years
      Your logger doesn't handle the entire exception or are you writing a logger?
    • Chris Sinclair
      Chris Sinclair over 10 years
      I'm assuming you actually use some utility (either third party logger, or your own class/implementation) so you aren't repeating the logging code itself wherever you need to try/catch/log? Also, I personally update it so it increases the initial tab indent (or you can use another mechanism) for each successive inner exception so when I read the logs I can distinguish the InnerException parent/child relationships rather than just getting a flat list of exceptions and trying to figure out where one stops and another starts. EDIT: And I prefix it with "INNER-EXCEPTION: "
    • CodeWarrior
      CodeWarrior over 10 years
      @MatthewWatson I didn't know about AggregateException until now! Thanks
    • CodeWarrior
      CodeWarrior over 10 years
      We do have a full-featured logger in production. However, sometimes we have to deploy certain quick fixes as a temporary workaround to a production problem. These quick fixes need to be developed rapidly to minimize losses and we don't want to use the application log for this.
    • user1703401
      user1703401 over 10 years
      Using ex.ToString() would be the better practice.
    • Kiquenet
      Kiquenet over 8 years
  • Gusdor
    Gusdor almost 8 years
    I'm logging ReflectionTypeLoadException using this method and it does not output the details from the nested LoaderException entries. I have to write a special case.
  • H.Wolper
    H.Wolper over 7 years
    Up-voted because of your update!
  • Sandeep
    Sandeep over 7 years
    JetBrains complains .ToSring() is not required on ex. Not sure why
  • D Stanley
    D Stanley over 7 years
    Some methods (like Console.WriteLine()) will implicitly call ToString when an object is passed in. There's no harm in removing it if it's not needed.
  • Lost_In_Library
    Lost_In_Library about 7 years
    I up-voted @H.Wolper because he up-voted (approved) the "Update" of old up-voted user.
  • Triynko
    Triynko over 5 years
    Exception.ToString is useless. I adapted the source code of AggregateException.Flatten to actually flatten all exceptions, not just AggregateExceptions, using the same basic non-recursive algorithm. This returns a flat list of Exceptions, which includes every exception, including AggrgateExceptions themselves and the individual exceptions therin, and their children, etc. This gives you the ability to filter out exceptions, by type, by message, etc. and finally construct a string with useful information. For example, you could filter out messages like "See the inner exception for details."
  • Matthew
    Matthew over 3 years
    @Maarten - Doesn't ex.ToString() not include any special attributes that the exception might have? Perhaps a FooException has an int FooSize and a string FooCode. These wouldn't be included in ToString();
  • Maarten
    Maarten over 3 years
    @Matthew You could be right. But the extension method in my answer also does not include that information either.