What is the best practice for capturing all inner exception details?
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.
Related videos on Youtube
CodeWarrior
Updated on April 16, 2020Comments
-
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 over 10 yearsYes, you might want to also handle AggregateException since they have an InnerExceptions property which you will otherwise miss.
-
Dustin Kingen over 10 yearsYour logger doesn't handle the entire exception or are you writing a logger?
-
Chris Sinclair over 10 yearsI'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 over 10 years@MatthewWatson I didn't know about AggregateException until now! Thanks
-
CodeWarrior over 10 yearsWe 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 over 10 yearsUsing ex.ToString() would be the better practice.
-
Kiquenet over 8 yearsMaybe useful extensionmethod.net/csharp/exception
-
-
Gusdor almost 8 yearsI'm logging
ReflectionTypeLoadException
using this method and it does not output the details from the nestedLoaderException
entries. I have to write a special case. -
H.Wolper over 7 yearsUp-voted because of your update!
-
Sandeep over 7 yearsJetBrains complains .ToSring() is not required on ex. Not sure why
-
D Stanley over 7 yearsSome methods (like
Console.WriteLine()
) will implicitly callToString
when an object is passed in. There's no harm in removing it if it's not needed. -
Lost_In_Library about 7 yearsI up-voted @H.Wolper because he up-voted (approved) the "Update" of old up-voted user.
-
Triynko over 5 yearsException.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 over 3 years@Maarten - Doesn't
ex.ToString()
not include any special attributes that the exception might have? Perhaps aFooException
has anint FooSize
and astring FooCode
. These wouldn't be included inToString();
-
Maarten over 3 years@Matthew You could be right. But the extension method in my answer also does not include that information either.