Exception.StackTraceEx - better exception stacktrace for async code

Last year I wrote about getting good exception stack traces for async code.

Now I've cleaned it up, made into a Portable Class Library, published the source code it under MIT-license on github and made precompiled binaries available as a NuGet package.

 

To recap: the goal is to get a user-experience like this, including line numbers and filenames, even on platforms like Phone which don't ship with PDBs:

 

To use the AsyncStackTraceEx nuget package:

  1. Right-click on your project > Manage NuGet Packages > search for "AsyncStackTraceEx" and install it
      
  2. You can change your Await DownloadAsync(url) statements into Await DownloadAsync(url) .Log()
  3. You can also provide more information: Await DownloadAsync(url) .Log("DownloadAsync",url)
  4. When you catch an exception, rather than using Exception.StackTrace, you'll get a more useful actionable callstack with Exception.StackTraceEx()
      

Here's a side-by-side comparison of the output.

Normal Exception.StackTrace(the highlighted parts are absent on phone since they depend on PDBs) Using AsyncStackTraceEx(the highlighted parts are present even on phone)
   at VB$StateMachine_3_BarAsync.MoveNext() in Class1.vb:line 24--- End of stack trace from previous location where exception was thrown ---   at TaskAwaiter.ThrowForNonSuccess(Task task)   at TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)   at TaskAwaiter.GetResult()   at VB$StateMachine_2_FooAsync.MoveNext() in Class1.vb:line 19--- End of stack trace from previous location where exception was thrown ---   at TaskAwaiter.ThrowForNonSuccess(Task task)   at TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)   at TaskAwaiter.GetResult()   at VB$StateMachine_1_TestAsync.MoveNext() in Class1.vb:line 14--- End of stack trace from previous location where exception was thrown ---   at TaskAwaiter.ThrowForNonSuccess(Task task)   at TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)   at TaskAwaiter`1.GetResult()   at VB$StateMachine_0_Button1_Click.MoveNext() in Class1.vb:line 5    at Test.BarAsync   at Test.FooAsync()#BarAsync in Class1.vb:19   at Test.TestAsync()#FooAsync(True) in Class1.vb:14   at Test.Button1_Click() in Class1.vb:5