By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
434,637 Members | 1,967 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 434,637 IT Pros & Developers. It's quick & easy.

Rethrowing an exception and preserving stack trace

P: n/a
If I got the following code:

try
{
// something that might throw an exception
}
catch (Exception ex)
{
// Log contents of ex here
throw;
}

this will rethrow the exception after logging it, however the stack
trace from there on will show the line of the "throw;" statement as the
first entry. If I drop the try/catch block here then the actual line of
code throwing the exception will be the first entry.

Using either "throw;" or "throw ex;" produces the same result, the
existing stack trace gets replaced with a new one starting with the
re-throwing statement.

Is there a way to fix this? Can I do something that will keep the
existing stack trace? Wether the re-throwing statement line and file
gets added to the stack trace or not is not important, I just don't want
to loose the history from the stack trace to that point.

Throwing a new exception and using the previous one as an InnerException
does not change it as only the new exceptions stack trace is reset,
however it seems a bit awkward to do this all over:

throw new SomeExceptionHere(ex.Message, ex);

just to keep the stack trace, and of course I would have to unwind the
tree of exceptions later on to rebuild the full stack trace anyway.

--
Lasse Vågsæther Karlsen
http://usinglvkblog.blogspot.com/
mailto:la***@vkarlsen.no
PGP KeyID: 0x2A42A1C2
Jan 17 '06 #1
Share this Question
Share on Google+
2 Replies


P: n/a

Lasse Vågsæther Karlsen wrote:
If I got the following code:

try
{
// something that might throw an exception
}
catch (Exception ex)
{
// Log contents of ex here
throw;
}

this will rethrow the exception after logging it, however the stack
trace from there on will show the line of the "throw;" statement as the
first entry. If I drop the try/catch block here then the actual line of
code throwing the exception will be the first entry.

Using either "throw;" or "throw ex;" produces the same result, the
existing stack trace gets replaced with a new one starting with the
re-throwing statement.


No - using throw; should be okay, but using throw ex; replaces the
stack trace.

Here's an example:

using System;
using System.Runtime.CompilerServices;

class Test
{
[MethodImpl(MethodImplOptions.NoInlining)]
static void InnerCall()
{
throw new Exception();
}

[MethodImpl(MethodImplOptions.NoInlining)]
static void OuterCall()
{
try
{
InnerCall();
}
catch
{
throw;
}
}
static void Main()
{
try
{
OuterCall();
}
catch (Exception e)
{
Console.WriteLine (e);
}
}
}

Output is:
System.Exception: Exception of type 'System.Exception' was thrown.
at Test.InnerCall()
at Test.OuterCall()
at Test.Main()

Changing the "throw;" to "throw ex;" (declaring the exception of
course) changes the output to:

System.Exception: Exception of type 'System.Exception' was thrown.
at Test.OuterCall()
at Test.Main()

I've included some attributes to ensure the JIT doesn't inline things.
They don't appear to make a difference in this case, but inlining may
explain why you've seen it not work in the past.

Jon

Jan 17 '06 #2

P: n/a
Jon Skeet [C# MVP] wrote:
Lasse Vågsæther Karlsen wrote:

<snip>
this will rethrow the exception after logging it, however the stack
trace from there on will show the line of the "throw;" statement as the
first entry. If I drop the try/catch block here then the actual line of
code throwing the exception will be the first entry.


<snip>
Changing the "throw;" to "throw ex;" (declaring the exception of
course) changes the output to:

System.Exception: Exception of type 'System.Exception' was thrown.
at Test.OuterCall()
at Test.Main()

I've included some attributes to ensure the JIT doesn't inline things.
They don't appear to make a difference in this case, but inlining may
explain why you've seen it not work in the past.

Jon


Thanks, I notice the same when I add the attributes, so then I know what
it is.
--
Lasse Vågsæther Karlsen
http://usinglvkblog.blogspot.com/
mailto:la***@vkarlsen.no
PGP KeyID: 0x2A42A1C2
Jan 18 '06 #3

This discussion thread is closed

Replies have been disabled for this discussion.