Giter VIP home page Giter VIP logo

asyncfriendlystacktrace's Introduction

Async-Friendly Stack Trace

Archived - no longer needed on .NET 5+

Note I have released version 1.7.0 of this package for .NET 6+ that basically calls StackTrace.ToString() and Exception.ToString() and adds Obsolete attributes, to alert users it is no longer needed.

Async-friendly format for stack traces and exceptions.

NuGet

Also check out Ben's Demystifier which resolves async, iterators, tuples, location functions and more.

System.Exception: Crash! Boom! Bang!
   at async AsyncFriendlyStackTrace.Test.Example1.C(?) in C:\Source\Repos\AsyncFriendlyStackTrace\src\AsyncFriendlyStackTrace.Test\Example1.cs:line 26
   at async AsyncFriendlyStackTrace.Test.Example1.B(?) in C:\Source\Repos\AsyncFriendlyStackTrace\src\AsyncFriendlyStackTrace.Test\Example1.cs:line 20
   at async AsyncFriendlyStackTrace.Test.Example1.A(?) in C:\Source\Repos\AsyncFriendlyStackTrace\src\AsyncFriendlyStackTrace.Test\Example1.cs:line 15
   at async AsyncFriendlyStackTrace.Test.Example1.Run(?) in C:\Source\Repos\AsyncFriendlyStackTrace\src\AsyncFriendlyStackTrace.Test\Example1.cs:line 10
   at AsyncFriendlyStackTrace.Test.Program.Run[TExample](TextWriter writer) in C:\Source\Repos\AsyncFriendlyStackTrace\src\AsyncFriendlyStackTrace.Test\Program.cs:line 45

Install

Install-Package AsyncFriendlyStackTrace

Usage

To format exceptions, use the extension methods in ExceptionExtensions:

exception.ToAsyncString();

This produces an async-friendly format, as you can see in the examples below. There is also special handling for AggregateExceptions and ReflectionTypeLoadException (which can contain multiple inner exceptions).

The main formatting work is done by the StackTraceExtensions.ToAsyncString extension method. The async-friendly formatting is archieved by:

  • Skipping all awaiter frames (all methods in types implementing INotifyCompletion) and ExceptionDispatchInfo frames.
  • Inferring the original method name from the async state machine class (IAsyncStateMachine) and removing the "MoveNext" - currently only for C#.
  • Adding the "async" prefix after "at" on each line for async invocations.
  • Appending "(?)" to the method signature to indicate that parameter information is missing.
  • Removing the "End of stack trace from previous location..." text.

Example outputs

In all the examples, OLD refrers to ToString() output, while NEW is ToAsyncString().

  • Example 1 (code): A simple 3 async method chain.
  • Example 2 (code): Async invocations with a synchronous Wait() in the middle, causing an AggregateException.
  • Example 3 (code): Bad Serialization - When exception is serialized and deserialized, its stack trace is saved as string. So we can't reformat the stack trace. The "new" stack trace is still a bit shorter due to an improved AggregateException formatting (the first inner exception isn't repeated twice).
  • Example 4 (code): Good Serialization - We use the PrepareForAsyncSerialization before serializing the exception. This saves the async-friendly stack trace as a string in the Data dictionary of the exception. This has two downsides:
    • The serialized data will now contain both stack trace formats.
    • When using the DataContractSerializer, you must include exception.Data.GetType() as a known type. This is because its concrete type (ListDictionaryInternal) is internal.

asyncfriendlystacktrace's People

Contributors

304notmodified avatar aelij avatar pruiz avatar rasmus-s avatar saxx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

asyncfriendlystacktrace's Issues

Signing problems in version 1.3 and 1.4

Problems when upgrade to version 1.3 or 1.4 i get this runtime exception:

Could not load file or assembly 'AsyncFriendlyStackTrace, Version=1.4.0.0, Culture=neutral, PublicKeyToken=f5fdf019656607c4' or one of its dependencies. Strong name signature could not be verified. The assembly may have been tampered with, or it was delay signed but not fully signed with the correct private key. (Exception from HRESULT: 0x80131045)

Looks like a signing issue, and sn.exe also say that the assembly is not valid:

C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin>sn -vf C:\Temp\AsyncFriendlyStackTrace.1.4.0\lib\net45\AsyncFriendlyStackTrace.dll

Microsoft (R) .NET Framework Strong Name Utility Version 3.5.30729.1
Copyright (c) Microsoft Corporation. All rights reserved.

Failed to verify assembly -- Strong name validation failed for assembly 'C:\Temp\AsyncFriendlyStackTrace.1.4.0\lib\net45\AsyncFriendlyStackTrace.dll'.

Running .net 4.5.1

"Instance field '_stackTraceString' is not defined" under linux/mono

Under Linux/Mono, I get this exception:

System.TypeInitializationException: An exception was thrown by the type initializer for AsyncFriendlyStackTrace.ExceptionExtensions ---> System.ArgumentException: Instance field '_stackTraceString' is not defined for type 'System.Exception'
  at System.Linq.Expressions.Expression.Field (System.Linq.Expressions.Expression expression, System.String fieldName) [0x00000] in <filename unknown>:0 
  at AsyncFriendlyStackTrace.ReflectionUtil.GenerateGetField[Exception,String] (System.String fieldName) [0x00000] in <filename unknown>:0 
  at AsyncFriendlyStackTrace.ExceptionExtensions..cctor () [0x00000] in <filename unknown>:0 
  --- End of inner exception stack trace ---

I imagine that the internal implementation of System.Exception in Mono is different than the "original" .NET implementation. I took a look at the sources, maybe it can be fixed using Exception.ToString() to get an exceptions stack trace, instead of using a private field? But I'm not sure about the RemoteStackTrace? (I don't even know what's this supposed to be, that's why I didn't submit a PR in the first place).

Unable to resolve dependency 'NETStandard.Library'

I tried to install the package in a .net 4.5.2 project but it was unable to install.

Failed with the message:

Unable to resolve dependency 'NETStandard.Library'. 
Source(s) used: 'api.nuget.org (v3)', 'nuget.org', 'Microsoft and .NET'.

Not all async related log lines supressed after ASP MVC nuget package upgrade

Not sure which package caused it - or even if the framework version is affecting this ('4.0.30319.42000') but I've just mass upgraded a lot of nuget packages to their latest versions today in an ASP MVC project and now my log lines are back to being much more verbose...

System.NullReferenceException: Object reference not set to an instance of an object.
   at Test.Services.Catalog.Models.Mappings.ProductMapper.<MapPrices>b__18_2(BaseOffer x) in C:\Source\test\src\Test.Services\Catalog\Models\Mappings\ProductMapper.cs:line 317
   at System.Linq.Enumerable.WhereSelectListIterator`2.MoveNext()
   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Test.Services.Catalog.Models.Mappings.ProductMapper.MapPrices(BaseProduct product, IEnumerable`1 alls, IEnumerable`1 priceCats, IEnumerable`1 priceTypes) in C:\Source\test\src\Test.Services\Catalog\Models\Mappings\ProductMapper.cs:line 311
   at async test.Services.Catalog.Models.Mappings.ProductMapper.<>c__DisplayClass16_0.<MapAsync>b__6(?) in C:\Source\test\src\Test.Services\Catalog\Models\Mappings\ProductMapper.cs:line 137
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at async Test.Services.Catalog.Models.Mappings.ProductMapper.MapAsync(?) in C:\Source\test\src\Test.Services\Catalog\Models\Mappings\ProductMapper.cs:line 92
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at async Test.Services.Catalog.ProductService.<GetByIdsWithNoContextInternalAsync>b__10_0(?) in C:\Source\test\src\Test.Services\Catalog\ProductService.cs:line 261
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at async Test.Caching.ICacheExtensions.MultiGetAsync[](?) in C:\Source\test\src\Test\Caching\ICacheExtensions.cs:line 61
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()

I'm 99% certain I never used to see at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() anywhere?

Let me know if you need any more details.

Handling of Task.Run() with anonymous Action/Func

Hi Eli

Cool stuff you got here! Trims away a lot of the (in most cases) unnecessary junk from logfiles. I have, however, encountered a scenario which is not supported that well. I'll leave it to you to decide whether it is a bug or not.

Consider the following example code illustrating the issue:

class Program
{
    static void Main(string[] args)
    {
        try
        {
            MyMethodAsync().Wait();
        }
        catch (Exception e)
        {
            var s1 = e.ToString();
            var s2 = e.ToAsyncString();
        }
    }

    private static async Task MyMethodAsync()
    {
        await Task.Run(async () =>
        {
            await Task.Run(() =>
            {
                MethodThrowingException();
            });
        });
    }

    private static void MethodThrowingException()
    {
        throw new NotImplementedException("Testing!");
    }
}

The value of s2 in the catch block of Main() will have an inner exception (#0) trace like this:

---> (Inner Exception #0) System.NotImplementedException: Testing!
at AsyncStacktraceTesting.Program.MethodThrowingException() in C:\Users\nche\Documents\AsyncStacktraceTesting\AsyncStacktraceTesting\Program.cs:line 38
at AsyncStacktraceTesting.Program.<>c.b__1_1() in C:\Users\nche\Documents\AsyncStacktraceTesting\AsyncStacktraceTesting\Program.cs:line 31
at System.Threading.Tasks.Task.InnerInvoke()
at System.Threading.Tasks.Task.Execute()
at async AsyncStacktraceTesting.Program.<>c.b__1_0(?) in C:\Users\nche\Documents\AsyncStacktraceTesting\AsyncStacktraceTesting\Program.cs:line 29
at async AsyncStacktraceTesting.Program.MyMethodAsync(?) in C:\Users\nche\Documents\AsyncStacktraceTesting\AsyncStacktraceTesting\Program.cs:line 27<---

As you can see, the anonymous action executing on line 29 is actually recognized as async, while the anonymous action on line 31 is not. Also the formatting of the method name could perhaps be improved, in such a case, while you're at it; not sure what it could be other than perhaps "anonymous" or something (perhaps Action or Func if you're able to differentiate) :-)

Like I said, I'm not even sure this is a defect or whether you have explicitly stated that this is not supported. But have a look and do what you want with it.

Installation issue with .net 4.5 projects

Install-Package AsyncFriendlyStackTrace
Installing 'AsyncFriendlyStackTrace 1.2.0'.
Successfully installed 'AsyncFriendlyStackTrace 1.2.0'.
Adding 'AsyncFriendlyStackTrace 1.2.0' to ConsoleApplication1.
Uninstalling 'AsyncFriendlyStackTrace 1.2.0'.
Successfully uninstalled 'AsyncFriendlyStackTrace 1.2.0'.
Install failed. Rolling back...
Install-Package : Could not install package 'AsyncFriendlyStackTrace 1.2.0'. You are trying to install this package into a project that targets '.NETFramework,Version=v4.5', but
the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author.At line:1 char:1

  • Install-Package AsyncFriendlyStackTrace
  • - CategoryInfo          : NotSpecified: (:) [Install-Package], InvalidOperationException
    - FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PowerShell.Commands.InstallPackageCommand
    

System.ArgumentException: Instance field 'stack_trace' is not defined for type 'System.Exception' when running on mono

Hi,

Since mono has been incorporating MS.NET source bits here and there, it looks like the reflection trick in order to obtain the internal field holding the stacktrace, no longer works in recent mono versions (at least on 5.8.x).

It looks like AsyncFriendlyStackTrace needs to be updated to try to guess wether Exception contains a field stack_trace, and if not, simply assume MS.NET field name instead.

Support `dnxcore50` framework

I'm still using RC1 of .NET Core and I want to wait to upgrade to the latest RC2 bits until it's finally released.

As far as I understand, with RC2 the frameworks will completely change (.NET Platform Standard), but for now I still work with dnxcore50 framework in my apps for .NET Core.

Unfortunately the AsyncFriendlyStackTrace NuGet package only support net451 and dotnet5.4 frameworks at the moment. So I cannot reference it from my dnxcore50 project.

Would it be possible to add dnxcore50 to the supported frameworks? I know that this would only be temporary until the .NET Platform Standard finally arrives, but it would help in my case until I can move on from RC1.

Support methods accepting Exception

Hi, thanks for great tool!

However it doesn't play that nicely with a logging method accepting Exception, such as TelemetryClient.TrackException(Exception).

Here's my current workaround:

    telemetryClient.TrackException(new Exception(context.Exception.ToAsyncString()));

But could be there a better way? For instance, reconstruct the actual, initial type of the exception.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.