129

For example, in one place...

//---------------a
try
{
    // some network call
}
catch(WebException we)
{
    throw new MyCustomException("some message ....", we);
}

...and in another place...

//--------------b
try
{
    // invoke code above
}
catch(MyCustomException we)
{
    Debug.Writeline(we.stacktrace);   // <----------------
}

The stacktrace I print, it only start from a to b, it doesnt include the inner stacktrace from the WebException.

How can I print all the stacktrace???

1
  • 3
    Note that the stacktrace for the originating WebException would not be printed because you threw a new exception rather than re-throwing the WebException. Use throw; in lieu of throw new MyCustomException(...) if you want to preserve (and output) the original exception stack.
    – Beel
    Commented Dec 25, 2016 at 13:19

4 Answers 4

232

I usually use the .ToString() method on exceptions to present the full exception information (including the inner stack trace) in text:

catch (MyCustomException ex)
{
    Debug.WriteLine(ex.ToString());
}

Sample output:

ConsoleApplication1.MyCustomException: some message .... ---> System.Exception: Oh noes!
   at ConsoleApplication1.SomeObject.OtherMethod() in C:\ConsoleApplication1\SomeObject.cs:line 24
   at ConsoleApplication1.SomeObject..ctor() in C:\ConsoleApplication1\SomeObject.cs:line 14
   --- End of inner exception stack trace ---
   at ConsoleApplication1.SomeObject..ctor() in C:\ConsoleApplication1\SomeObject.cs:line 18
   at ConsoleApplication1.Program.DoSomething() in C:\ConsoleApplication1\Program.cs:line 23
   at ConsoleApplication1.Program.Main(String[] args) in C:\ConsoleApplication1\Program.cs:line 13
4
  • Very good. I was looking for a simple way to do it and here it is. Some little concern is it is not as much explicit as if you use exception.StackTrace object (for example). I wonder if there is a more explicit way to do the same?
    – codea
    Commented May 7, 2014 at 16:29
  • 8
    Be aware that some libraries override the ToString method and print custom messages instead of the full information (this is a bad coding practice, so do not do that, ever)
    – Dinei
    Commented Jan 28, 2016 at 18:05
  • @Pரதீப் I use ToString whenever I'm sure it is not overwritten, and use the properties directly otherwise (like Andrew Hare's answer).
    – Dinei
    Commented Aug 24, 2018 at 14:25
  • 3
    Silly me for using exception.StackTrace and thinking it would work Commented Nov 17, 2020 at 23:13
63

Use a function like this:

    public static string FlattenException(Exception exception)
    {
        var stringBuilder = new StringBuilder();

        while (exception != null)
        {
            stringBuilder.AppendLine(exception.Message);
            stringBuilder.AppendLine(exception.StackTrace);

            exception = exception.InnerException;
        }

        return stringBuilder.ToString();
    }

Then you can call it like this:

try
{
    // invoke code above
}
catch(MyCustomException we)
{
    Debug.Writeline(FlattenException(we));
}
5
  • 16
    Or you can use ToString?
    – Justin
    Commented Nov 24, 2010 at 23:55
  • I'm using the ToString and think it's fine. I'd go with Andrew's solution if i only want the lowest inner exception (with the actual reason) or similar picking.. works both though :)
    – EeKay
    Commented May 1, 2013 at 8:24
  • 1
    This is more flexible that just ToString, because you can choose what goes into that string. Maybe I'm only interested in the stack traces, not necessarily the messages. Or I want it as a List<string> not a single string. Commented Sep 9, 2019 at 9:28
  • What about the inner exceptions?
    – Clark
    Commented Sep 23, 2020 at 14:05
  • @Clark Originally (in .NET Framework 2.0 through 3.5) Exception.ToString() did not output details of InnerException (or AggregateException.InnerExceptions) however I believe since .NET Framework 4.0 (which post-dates this answer, as it came out in late 2010 IIRC) does include the InnerException object-graph in ToString()'s output.
    – Dai
    Commented Dec 26, 2020 at 6:51
25

1. Create Method: If you pass your exception to the following function, it will give you all methods and details which are reasons of the exception.

public string GetAllFootprints(Exception x)
{
        var st = new StackTrace(x, true);
        var frames = st.GetFrames();
        var traceString = new StringBuilder();

        foreach (var frame in frames)
        {
            if (frame.GetFileLineNumber() < 1)
                continue;

            traceString.Append("File: " + frame.GetFileName());
            traceString.Append(", Method:" + frame.GetMethod().Name);
            traceString.Append(", LineNumber: " + frame.GetFileLineNumber());
            traceString.Append("  -->  ");
        }

        return traceString.ToString();
}

2. Call Method: You can call the method like this.

try
{
    // code part which you want to catch exception on it
}
catch(Exception ex)
{
    Debug.Writeline(GetAllFootprints(ex));
}

3. Get the Result:

File: c:\MyProject\Program.cs, Method:MyFunction, LineNumber: 29  -->  
File: c:\MyProject\Program.cs, Method:Main, LineNumber: 16  --> 
3
2

Recommend to use LINQPad related nuget package, then you can use exceptionInstance.Dump().

enter image description here

For .NET core:

  • Install LINQPad.Runtime

For .NET framework 4 etc.

  • Install LINQPad

Sample code:

using System;
using LINQPad;

namespace csharp_Dump_test
{
    public class Program
    {
        public static void Main()
        {
            try
            {
                dosome();
            }
            catch (Exception ex)
            {
                ex.Dump();
            }
        }

        private static void dosome()
        {
            throw new Exception("Unable.");
        }
    }
}

Running result: enter image description here

LinqPad nuget package is the most awesome tool for printing exception stack information. May it be helpful for you.

Not the answer you're looking for? Browse other questions tagged or ask your own question.