Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Attach StackTrace To Exception Without Throwing in C# / .NET

Tags:

c#

.net

I have a component which handles errors using return values as opposed to standard exception handling. In addition to the error code, it also returns a stack trace of where the error has occurred. A wrapper I use to invoke the component will interpret return codes and throw an exception.

I'd like to have the wrapper throw an exception that includes the captured stack trace information from the component. I'd like it to appear as if the exception had been thrown from the original site of the error even though it was thrown elsewhere. More specifically, I'd like the stack trace displayed by the Visual Studio test runner to reflect the proper location.

Is there any way to do this? It would also be nice if I could avoid low-level reflection tricks accessing private members but I will take what I can get.

I'm not concerned with how to capture a stack trace, I'm concerned with attaching a stack trace that's already been captured, to an Exception.

I tried overriding the StackTrace property, but Visual Studio is pulling the stack trace data from somewhere else, and seems to ignore the overridden property completely

CustomException GenerateExcpetion() {     return new CustomException(); }  void ThrowException(Exception ex) {     Trace.WriteLine("Displaying Exception");     Trace.WriteLine(ex.ToString());     var edi = ExceptionDispatchInfo.Capture(ex);     edi.Throw(); }  [TestMethod] public void Test006() {     var ex = GenerateExcpetion();     ThrowException(ex); }  public class CustomException : Exception {     string _stackTrace;     public CustomException()     {         _stackTrace = Environment.StackTrace;     }      public override string StackTrace     {         get         {             return base.StackTrace;         }     } } 

The Exception.ToString() method pulls stack trace data from a private property, and so the stack trace coming from the override doesn't get shown.

CustomException: Exception of type 'CustomException' was thrown.

The ExceptionDispatchInfo looks for the stack trace data from a private property as well, and so it can't find any of that data, and when you throw this custom exception a new stack trace is attached to the exception with the location that it is being thrown from. If you use throw directly, the private stack information is set to the place where the throw happened.

like image 605
hannasm Avatar asked May 07 '16 20:05

hannasm


1 Answers

Just create your own Exception type and override the StackTrace property:

class MyException : Exception {     private string oldStackTrace;      public MyException(string message, string stackTrace) : base(message)     {         this.oldStackTrace = stackTrace;     }       public override string StackTrace     {         get         {             return this.oldStackTrace;         }     } } 
like image 121
adjan Avatar answered Sep 19 '22 09:09

adjan