Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I preserve the stack trace when exception is thrown on non-UI thread

Tags:

c#

exception

wpf

Doing this is bad form because it doesn't preserve a stack trace:

try { /*... some code that can throw an exception ...*/ }
catch (Exception e)
{
    throw e; // ...Use "throw;" by itself instead
}

However, if the exception is caught on a non-UI thread, I want to do raise it back up to the UI and handle it so the user gets the message like so:

try { /*... some code that can throw an exception ...*/ }
catch (Exception e)
{
    Dispatcher.Invoke((Action)(() => { throw; }));
}

However, I can't use the throw keyword by itself here because the C# lexer (correctly) doesn't think the throw statement is inside of a catch. I have to instead do:

try { /*... some code that can throw an exception ...*/ }
catch (Exception e)
{
    Dispatcher.Invoke((Action)(() => { throw e; }));
}

and re-throw the exception, which loses its stack trace.

Is there any (easy) way to get around this (I could always package the stack trace at the time the exception is ready to switch threads, but that seems hokey)?

Note: I saw this thread but it's similar in title only, not content.

like image 375
Michael Avatar asked Feb 01 '13 19:02

Michael


People also ask

Should stack traces be logged?

Logging the stack traces of runtime exceptions assists developers in diagnosing runtime failures. However, unnecessary logging of exception stack traces can have many negative impacts such as polluting log files.

What does end of stack trace from previous location where exception was thrown mean?

When the exception is restored, the following string is inserted in the stack trace to indicate the restore point: "End of stack trace from the previous location where the exception was thrown". This is similar to the way inner exceptions or marshaled exceptions are indicated in stack traces.

When should you Rethrow an exception?

If a catch block cannot handle the particular exception it has caught, you can rethrow the exception. The rethrow expression ( throw without assignment_expression) causes the originally thrown object to be rethrown.


1 Answers

The usual way to do this is to throw a new exception, with the original included as InnerException. Exception has a special constructor for this.

But if you really want to do this and you're on .Net 4.5, you can use ExceptionDispatchInfo to capture the stack trace of the exception and then rethrowing it somewhere else without resetting the stack trace. But in most situations, using the old method of wrapping the exception in a new one is probably better.

like image 104
svick Avatar answered Sep 18 '22 13:09

svick