How to customize the stacktrace of a custom Exception?
-
Monday, August 13, 2012 2:24 PM
The Exception.StackTrace propery is virtual and can be overridden to define something else, however as of .NET 4 Exception.ToString() ignores this and keeps on using the build in functionality.
Small example to show the difference in behavior:
class Program { static void Main(string[] args) { try { Test1(); } catch (Exception e) { Console.WriteLine("Main() =>" + Environment.NewLine + "StackTrace: " + e.StackTrace + Environment.NewLine + "ToString: " + e.ToString() + Environment.NewLine); } Console.ReadKey(); } private static void Test1() { try { Test2(); } catch (Exception e) { Console.WriteLine("Test1() =>" + Environment.NewLine + "StackTrace: " + e.StackTrace + Environment.NewLine + "ToString: " + e.ToString() + Environment.NewLine); throw new Exception("Inner exception", e); // Throw with inner exception } } private static void Test2() { try { Test3(); } catch (Exception e) { Console.WriteLine("Test2() =>" + Environment.NewLine + "StackTrace: " + e.StackTrace + Environment.NewLine + "ToString: " + e.ToString() + Environment.NewLine); throw; // Rethrow } } private static void Test3() { throw new MyException(); } } public class MyException : Exception { public override string StackTrace { get { return " at: My custom StackTrace..."; } } }With .NET 4 produces:
Test2() =>
StackTrace: at: My custom StackTrace...
ToString: exception.MyException: Exception of type 'exception.MyException' was thrown.
at exception.Program.Test3() in d:\Projects\exception\exception\Program.cs:line 53
at exception.Program.Test2() in d:\Projects\exception\exception\Program.cs:line 41
Test1() =>
StackTrace: at: My custom StackTrace...
ToString: exception.MyException: Exception of type 'exception.MyException' was thrown.
at exception.Program.Test3() in d:\Projects\exception\exception\Program.cs:line 53
at exception.Program.Test2() in d:\Projects\exception\exception\Program.cs:line 47
at exception.Program.Test1() in d:\Projects\exception\exception\Program.cs:line 28
Main() =>
StackTrace: at exception.Program.Test1() in d:\Projects\exception\exception\Program.cs:line 33
at exception.Program.Main(String[] args) in d:\Projects\exception\exception\Program.cs:line 14
ToString: System.Exception: Inner exception ---> exception.MyException: Exception of type 'exception.MyException' was thrown.
at exception.Program.Test3() in d:\Projects\exception\exception\Program.cs:line 53
at exception.Program.Test2() in d:\Projects\exception\exception\Program.cs:line 47
at exception.Program.Test1() in d:\Projects\exception\exception\Program.cs:line 28
--- End of inner exception stack trace ---
at exception.Program.Test1() in d:\Projects\exception\exception\Program.cs:line 33
at exception.Program.Main(String[] args) in d:\Projects\exception\exception\Program.cs:line 14with .NET 3.5 produces:
Test2() =>
StackTrace: at: My custom StackTrace...
ToString: exception.MyException: Exception of type 'exception.MyException' was thrown.
at: My custom StackTrace...
Test1() =>
StackTrace: at: My custom StackTrace...
ToString: exception.MyException: Exception of type 'exception.MyException' was thrown.
at: My custom StackTrace...
Main() =>
StackTrace: at exception.Program.Test1() in d:\Projects\ConsoleApplication3\ConsoleApplication3\Program.cs:line 33
at exception.Program.Main(String[] args) in d:\Projects\ConsoleApplication3\ConsoleApplication3\Program.cs:line 14
ToString: System.Exception: Inner exception ---> exception.MyException: Exception of type 'exception.MyException' was thrown.
at: My custom StackTrace...
--- End of inner exception stack trace ---
at exception.Program.Test1() in d:\Projects\ConsoleApplication3\ConsoleApplication3\Program.cs:line 33
at exception.Program.Main(String[] args) in d:\Projects\ConsoleApplication3\ConsoleApplication3\Program.cs:line 14.NET 3.5 behavior is according to how I interpreter the documentation.
In an attempt to solve it I overridden the ToSting(), this only solves the problem partially. For the case without a inner exception the output is then ok, but when calling the ToString() on the outer exception the stack trace of the inner exception logged in the output of the ToString() is still wrong.
Is there any other way to specify custom stack format/data?
All Replies
-
Tuesday, August 14, 2012 3:46 AMModerator
Hi Hvleem,
Welcome to the MSDN Forum.
I have tried your code and get the same result of yours.
From the result, you own stack trace works well. It always returns "at: My custom StackTrace...", doesn't it?
The difference is the toString method. Based on the test, the toString method in .net 3.5 is different from 4.0's. So to achieve your goal, you also need to custom the toString method.
Best regards,
Mike Feng
MSDN Community Support | Feedback to us
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
-
Tuesday, August 14, 2012 6:13 AM
Hi Mike,
Yes calling the customized StackTrace property works well.
Your suggestion to override the ToString() method will only work partially, at least when I tried it. Here is the code I used to test it:
class Program { static void Main(string[] args) { try { Test1(); } catch (Exception e) { Console.WriteLine("Main() =>" + Environment.NewLine + "StackTrace: " + e.StackTrace + Environment.NewLine + "ToString: " + e.ToString() + Environment.NewLine); } Console.ReadKey(); } private static void Test1() { try { Test2(); } catch (Exception e) { Console.WriteLine("Test1() =>" + Environment.NewLine + "StackTrace: " + e.StackTrace + Environment.NewLine + "ToString: " + e.ToString() + Environment.NewLine); throw new Exception("Inner exception", e); // Throw with inner exception } } private static void Test2() { try { Test3(); } catch (Exception e) { Console.WriteLine("Test2() =>" + Environment.NewLine + "StackTrace: " + e.StackTrace + Environment.NewLine + "ToString: " + e.ToString() + Environment.NewLine); throw; // Rethrow } } private static void Test3() { throw new MyException(); } } public class MyException : Exception { public override string StackTrace { get { return " at: My custom StackTrace..."; } } public override String ToString() { String str = GetType().Name; String message = Message; if (message != null && message.Length > 0) { str = str + ": " + message; } Exception innerException = InnerException; if (innerException != null) { str = str + " ---> " + innerException.ToString() + Environment.NewLine + " --- End of inner exception stack trace ---" + Environment.NewLine; } string stackTrace = StackTrace; if (stackTrace != null) { str += Environment.NewLine + stackTrace; } return str; } }
It results in (with .NET 4):
Test2() =>
StackTrace: at: My custom StackTrace...
ToString: MyException: Exception of type 'exception.MyException' was thrown.
at: My custom StackTrace...
Test1() =>
StackTrace: at: My custom StackTrace...
ToString: MyException: Exception of type 'exception.MyException' was thrown.
at: My custom StackTrace...
Main() =>
StackTrace: at exception.Program.Test1() in d:\exception\exception\Program.cs:line 33
at exception.Program.Main(String[] args) in d:\exception\exception\Program.cs:line 14
ToString: System.Exception: Inner exception ---> exception.MyException: Exception of type 'exception.MyException' was thrown.
at exception.Program.Test3() in d:\exception\exception\Program.cs:line 53
at exception.Program.Test2() in d:\exception\exception\Program.cs:line 47
at exception.Program.Test1() in d:\exception\exception\Program.cs:line 28
--- End of inner exception stack trace ---
at exception.Program.Test1() in d:\exception\exception\Program.cs:line 33
at exception.Program.Main(String[] args) in d:\exception\exception\Program.cs:line 14As you can see the ToString() method is not called correctly in case my exception with modified stack is re thrown as an inner exception.
The System.Exception does not seem to call the ToString() of the inner exception, it rather seems to get the inner exception data via private methods/properties.
Any suggestion on how to get a consistent behavior in all these cases?
Kind regards,
Hans
-
Tuesday, August 14, 2012 8:38 AMModerator
Hi Hans,
Yes, I reproduced it.
You can submit this feedback here: http://connect.microsoft.com/VisualStudio/
Microsoft will check it later.
When you finish it, please post the link here so the other community members can also track this issue easily.
Thank you.
Best regards,
Mike Feng
MSDN Community Support | Feedback to us
Please remember to mark the replies as answers if they help and unmark them if they provide no help.
-
Friday, August 17, 2012 2:23 PM
Issue submitted as: 75850
The issue has been closed as "won't be fixed", for more details see the issue.
Regards,
- Marked As Answer by Mike FengMicrosoft Contingent Staff, Moderator Monday, August 20, 2012 8:31 AM
- Edited by hvleem Thursday, August 30, 2012 6:20 AM

