views:

236

answers:

3

Is it possible to throw an exception (could be any exception) with a customized stack trace?

As a concrete example: lets say I have a set of some small static utility methods which might throw exceptions. However I would like the exception to appear to have originated from the previous method instead of the utility method (I want to ignore the 1st frame of the trace).

A: 

Catch it in the outer method & create a new exception and throw it.


try
{
   Class.StaticMethod();
}
catch (Exception e)
{
   throw new Exception("Some error occurred");
}

shahkalpesh
Oops, I guess I misunderstood the question. Sorry about that.
shahkalpesh
Let me know, if you would like me to delete it. This doesn't add any value.
shahkalpesh
A: 

The StackTrace property is virtual - create your own derived Exception class and have the property return whatever you want.

James Cadd
I would do this except I'd prefer to throw the original Exception type. And I don't want to pass it around as an inner exception.
Joseph Daigle
+2  A: 

Messing around with the stack trace really doesn't sound like a good idea, even if it is possible (I'm doubtful of that). Tell me, why would you want to do that anyway? The .NET framework itself (the BCL) often uses static utility methods to throw exceptions, in the way that you suggest (ThrowHelper is its name in at least some parts of the framework), and it certainly does hide anything in the stack trace.

Here's an example stack trace from a test I just ran:

   at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource)
   at System.ThrowHelper.ThrowArgumentOutOfRangeException()
   at System.Collections.Generic.List`1.get_Item(Int32 index)
   at HelloWorld.Program.Main(String[] args) in C:\...\Program.cs:line 23
   at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
   at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

As you can see, the BCL uses the ThrowArgumentOutOfRangeException method, and it's clearly visible in the stack trace. If you want to mark the helper method with the DebuggerNonUserCode attribute, then that would seem fair enough to me (though it's not done in the BCL).

Noldorin
I suppose you're right actually. The main reason I wanted to do this was to "pretty up" debugging these exceptions when thrown. However I think the better way to accomplish what I want is to use the [DebuggerNonUserCode] attribute on my methods.
Joseph Daigle
Yeah, I see exactly where you're coming from. The .NET helper methods don't use the DebuggerNonUserCode attribute, but it sounds like a sensible idea to me.
Noldorin