GithubHelp home page GithubHelp logo

benaadams / ben.demystifier Goto Github PK

View Code? Open in Web Editor NEW
2.7K 74.0 118.0 426 KB

High performance understanding for stack traces (Make error logs more productive)

License: Apache License 2.0

C# 99.24% PowerShell 0.76%
stack-traces aspnet-core dotnet dotnet-core error-handling error-messages exceptions

ben.demystifier's People

Contributors

alexanderkozlenko avatar alexandersher avatar benaadams avatar bruno-garcia avatar dependabot[bot] avatar drawaes avatar georgeduckett avatar horusiath avatar jnyrup avatar joestead avatar khellang avatar kirillosenkov avatar mitchcapper avatar nickcraver avatar onyxmaster avatar pengweiqhca avatar rgmills avatar samtrion avatar satano avatar sergeyteplyakov avatar sharon-lin avatar simoncropp avatar suchiman avatar tylerap avatar willl avatar zoxive 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  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

ben.demystifier's Issues

Path separater is "wrong" on Windows

Maybe this is "as designed", but I noticed that Ben.Demystifier uses forward-slashes for path separators, and not backslashes, as the normal exception stack trace on Windows. It this intentional, for it to be the same across all platforms, or unintentional?

Demystify some more esoteric stack traces

Hi!

Is it possible to improve readability of the bold marked lines?

Application startup exception: System.Net.Sockets.SocketException (61): Connection refused
at Npgsql.NpgsqlConnector.Connect(NpgsqlTimeout timeout) in C:\projects\npgsql\src\Npgsql\NpgsqlConnector.cs:line 704
at Npgsql.NpgsqlConnector.RawOpen(NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken) in C:\projects\npgsql\src\Npgsql\NpgsqlConnector.cs:line 555
at Npgsql.NpgsqlConnector.Open(NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken) in C:\projects\npgsql\src\Npgsql\NpgsqlConnector.cs:line 414
at Npgsql.NpgsqlConnection.<>c__DisplayClass32_0.<g__OpenLong|0>d.MoveNext() in C:\projects\npgsql\src\Npgsql\NpgsqlConnection.cs:line 272
--- End of stack trace from previous location where exception was thrown ---
at Npgsql.NpgsqlConnection.Open() in C:\projects\npgsql\src\Npgsql\NpgsqlConnection.cs:line 153
at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlDatabaseCreator.Exists() in C:\projects\npgsql-entityframeworkcore-postgresql\src\EFCore.PG\Storage\Internal\NpgsqlDatabaseCreator.cs:line 216
at Microsoft.EntityFrameworkCore.Migrations.HistoryRepository.Exists()
at Microsoft.EntityFrameworkCore.Migrations.Internal.Migrator.Migrate(String targetMigration)
at Microsoft.EntityFrameworkCore.RelationalDatabaseFacadeExtensions.Migrate(DatabaseFacade databaseFacade)
at Sapphire.EntityFrameworkCore.Extensions.ServiceProviderExtensions.MigrateDatabase[TContext](IServiceProvider serviceProvider) in /Users/krisztian.kocsis/Documents/Projects/miw-cloud/modules/sapphire/src/Sapphire.EntityFrameworkCore/Extensions/ServiceProviderExtensions.cs:line 41
at MIW.Cloud.Web.Bootstrap.Configure(IApplicationBuilder applicationBuilder) in /Users/krisztian.kocsis/Documents/Projects/miw-cloud/src/MIW.Cloud.Web/Bootstrap.cs:line 135
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.AspNetCore.Hosting.ConventionBasedStartup.Configure(IApplicationBuilder app)
at Microsoft.AspNetCore.HostFilteringStartupFilter.<>c__DisplayClass0_0.b__0(IApplicationBuilder app)
at Microsoft.AspNetCore.Hosting.Internal.AutoRequestServicesStartupFilter.<>c__DisplayClass0_0.b__0(IApplicationBuilder builder)
at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()

NuGet dependency mismatch between ValueTuple and framework version

The Ben.Demystifier package has these dependencies:
image

I'm using .NET 4.5 and this is causing issues because System.ValueTuple 4.4.0 have the dependency .NETFramework, Version=v4.6.1

Either Ben.Demystifier should also have .NETFramework, Version=v4.6.1 or it should use System.ValueTuple 4.3.1

Support filtering frames

We've hit a scenario where we want to reduce additional noise from framework components to cut down logging costs.

Specific scenario we have is with ASP.NET MVC and ActionFilterAttributes, we have several registered and it results in a fair amount of excessive information in the logs, for example:

   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.ExecuteActionFilterAsyncCore(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.ExecuteActionFilterAsyncCore(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.ExecuteActionFilterAsyncCore(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.ExecuteActionFilterAsyncCore(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.ExecuteActionFilterAsyncCore(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.ExecuteActionFilterAsyncCore(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.ExecuteActionFilterAsyncCore(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.ExecuteActionFilterAsyncCore(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.ExecuteActionFilterAsyncCore(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.ExecuteActionFilterAsyncCore(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.ExecuteActionFilterAsyncCore(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.ExecuteActionFilterAsyncCore(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.ExecuteActionFilterAsyncCore(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.CallOnActionExecutedAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
   at async Task<HttpResponseMessage> System.Web.Http.Filters.ActionFilterAttribute.ExecuteActionFilterAsyncCore(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)

This is included in any stack trace as from our API and represents about 75% of the stacktrace itself. Do you think there would be value in supporting some filtering mechanism to allow consumers to reduce the output?

Support for html/custom formatting

Hi,

This library is great for improving a raw stacktrace (thanks!). I'd love to be able to easily format its output for display on a web page or email too, without having to resort to Regex or parsing the string output.

Looking at the various Append methods it looks like this should be possible, however I'm not quite sure what an API would look like, or whether this request belongs within this library at all.

My first thought would be creating equivalent methods to the Append ones that returned an enumerable token list (consisting of string and token type) rather than appending to a StringBuilder. The consumer could then iterate over the list inserting formatting sections between the strings as appropriate. Another option could be simply surrounding relevant output with <span> tags, however this would be pretty inflexible and would have to handle html encoding. An 3rd option could be creating a FormatSettings class that defines various strings to insert before/after certain tokens.

Would be great to hear any thoughts on the above.

0.1.2 ToStringDemystified() misses exception detail

			Exception ex = null;
			try
			{
				throw new InvalidOperationException("aaa")
				{
					Data =
					{
						["bbb"] = "ccc",
						["ddd"] = "eee",
					}
				};
			}
			catch (Exception e)
			{
				ex = e;
			}
			var str = ex.ToStringDemystified();

0.1.1 output

System.InvalidOperationException: aaa
   at void Tests.CommonTests.ExceptionDemistyfierTests.TestDemistifyWithData() in D:/.../Infrastructure.Tests/CommonTests/ExceptionDemistyfierTests.cs:line 47

0.1.2 output

   at void Tests.CommonTests.ExceptionDemistyfierTests.TestDemistifyWithData() in D:/.../Infrastructure.Tests/CommonTests/ExceptionDemistyfierTests.cs:line 47

BTW, the corresponding test is broken.

                var original = e.ToString();
                var stringDemystified = e.ToStringDemystified();

                _output.WriteLine("Demystified: ");
                _output.WriteLine(stringDemystified);

                _output.WriteLine("Original: ");
                var afterDemystified = e.ToString(); // <-- here
                _output.WriteLine(afterDemystified);

                Assert.Equal(original, afterDemystified);

Assemblies in NuGet package are not signed with Authenticode

Is it possible to sign the assemblies with Authenticode ?

C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x64>signtool verify "C:\Users\sezhezhe\.nuget\packages\ben.demystifier\0.1.4\lib\netstandard2.0\Ben.Demystifier.dll"
File: C:\Users\sezhezhe\.nuget\packages\ben.demystifier\0.1.4\lib\netstandard2.0\Ben.Demystifier.dll
Index  Algorithm  Timestamp
========================================
SignTool Error: No signature found.

Number of errors: 1

Not compatible with Microsoft.CodeAnalysis.Csharp

First of all thanks a lot, it's very useful to have relevant StackTraces.

Unfortunately I am one of these poor guy that needs to use strongnames. So we used strongnamer which works perfectly. However once you strongname you really need similar versions.

Ben.Demystifier requires System.Reflection.Metadata 1.5.0, which requires System.Collections.Immutable 1.4.0

We also use Microsoft.CodeAnalysis.Csharp, but unfortunately it uses Microsoft.CodeAnalysis.Common 2.4.0, which uses System.Collections.Immutable 1.3.1

So when running the runtime is obviously unhappy.
Do you see a way to make both cohabit?

async lambda not Demystified

Throwing from async lambda like so

namespace SomeNamespace
{
  public static class SomeClass
  {
    public static void ThrowsSomethingAsync()
    {
      Func<Task> f = async () => throw new Exception("Some exception");
      f().ConfigureAwait(false).GetAwaiter().GetResult();
    }
  }
}

Transforms

   at SomeNamespace.SomeClass.<>c.<<ThrowsSomethingAsync>b__0_0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
   at SomeNamespace.SomeClass.ThrowsSomethingAsync()

into

   at void SomeNamespace.SomeClass+<>c+<<ThrowsSomethingAsync>b__0_0>d.MoveNext()
   at void SomeNamespace.SomeClass.ThrowsSomethingAsync()

without async I get

   at void SomeNamespace.SomeClass.ThrowsSomethingAsync()+() => { }
   at void SomeNamespace.SomeClass.ThrowsSomethingAsync()

Source file paths from SourceLinked binaries aren't appended

I am demystifying a first-chance exception that happens in Roslyn. Roslyn source-links all their assemblies, so the file paths in the .pdb look like:

/_/src/EditorFeatures/Core.Wpf/Suggestions/SuggestedActionsSource.cs

Unfortunately constructing a new Uri with that string throws:

There are three problems with this:

  1. An additional first-chance exception is generated as a side-effect of demystifying. In a system that I'm building we have tightly controlled first-chance exceptions (and ironically, this is where I'm using Demystify - to pretty-print first-chance exceptions and categorize them properly). Having an avoidable first-chance exception here is a deal-breaker for us.
  2. The source code path for this stack frame is lost.
  3. Since this is happening for every frame with that pattern of source file path, it's a non-trivial perf penalty since the exception is thrown per frame.

I'm thinking if one could avoid constructing a new Uri here and rewrite the code in a different way.

Thanks!

Some stacks cannot be captured because GetMethodDisplayString doesn't handle generic types

  HResult=0x80131509
  Message=Late bound operations cannot be performed on fields with types for which Type.ContainsGenericParameters is true.
  Source=System.Private.CoreLib
  StackTrace:
   at System.Reflection.RtFieldInfo.InternalGetValue(Object obj, StackCrawlMark& stackMark)
   at System.Reflection.RtFieldInfo.GetValue(Object obj)
   at System.Diagnostics.EnhancedStackTrace.GetMethodDisplayString(MethodBase originMethod) in C:\GitHub\Ben.Demystifier\src\Ben.Demystifier\EnhancedStackTrace.Frames.cs:line 142
   at System.Diagnostics.EnhancedStackTrace.GetFrames(StackTrace stackTrace) in C:\GitHub\Ben.Demystifier\src\Ben.Demystifier\EnhancedStackTrace.Frames.cs:line 70
   at System.Diagnostics.EnhancedStackTrace..ctor(StackTrace stackTrace) in C:\GitHub\Ben.Demystifier\src\Ben.Demystifier\EnhancedStackTrace.cs:line 47
   at System.Diagnostics.EnhancedStackTrace.Current() in C:\GitHub\Ben.Demystifier\src\Ben.Demystifier\EnhancedStackTrace.cs:line 14
   at Sparrow.NativeAllocator`1.Initialize(NativeAllocator`1& allocator) in F:\ravendb-4.0\src\Sparrow\Allocators.Native.cs:line 106

The real stack trace is:

   at System.Environment.get_StackTrace()
   at System.Reflection.RtFieldInfo.InternalGetValue(Object obj, StackCrawlMark& stackMark)
   at System.Reflection.RtFieldInfo.GetValue(Object obj)
   at System.Diagnostics.EnhancedStackTrace.GetMethodDisplayString(MethodBase originMethod) in C:\GitHub\Ben.Demystifier\src\Ben.Demystifier\EnhancedStackTrace.Frames.cs:line 142
   at System.Diagnostics.EnhancedStackTrace.GetFrames(StackTrace stackTrace) in C:\GitHub\Ben.Demystifier\src\Ben.Demystifier\EnhancedStackTrace.Frames.cs:line 70
   at System.Diagnostics.EnhancedStackTrace..ctor(StackTrace stackTrace) in C:\GitHub\Ben.Demystifier\src\Ben.Demystifier\EnhancedStackTrace.cs:line 47
   at System.Diagnostics.EnhancedStackTrace.Current() in C:\GitHub\Ben.Demystifier\src\Ben.Demystifier\EnhancedStackTrace.cs:line 14
   at Sparrow.NativeAllocator`1.Initialize(NativeAllocator`1& allocator) in F:\ravendb-4.0\src\Sparrow\Allocators.Native.cs:line 106
   at Sparrow.ArenaAllocator`1.Initialize(ArenaAllocator`1& allocator) in F:\ravendb-4.0\src\Sparrow\Allocators.Arena.cs:line 126
   at Sparrow.Allocator`1.Initialize[TAllocatorOptions](TAllocatorOptions options) in F:\ravendb-4.0\src\Sparrow\Allocators.cs:line 129
   at Sparrow.Json.JsonOperationContext.Renew() in F:\ravendb-4.0\src\Sparrow\Json\JsonOperationContext.cs:line 970
   at Sparrow.Json.JsonContextPoolBase`1.TryReuseExistingContextFrom(ContextStack stack, T& context, IDisposable& disposable) in F:\ravendb-4.0\src\Sparrow\Json\JsonContextPoolBase.cs:line 173
   at Sparrow.Json.JsonContextPoolBase`1.AllocateOperationContext(T& context) in F:\ravendb-4.0\src\Sparrow\Json\JsonContextPoolBase.cs:line 138
   at Sparrow.Json.JsonOperationContext.ManagedPinnedBuffer.Clone[T](JsonContextPoolBase`1 pool) in F:\ravendb-4.0\src\Sparrow\Json\JsonOperationContext.cs:line 215
   at Raven.Server.Documents.Replication.IncomingReplicationHandler..ctor(TcpConnectionOptions options, ReplicationLatestEtagRequest replicatedLastEtag, ReplicationLoader parent, ManagedPinnedBuffer bufferToCopy) in F:\ravendb-4.0\src\Raven.Server\Documents\Replication\IncomingReplicationHandler.cs:line 75
   at Raven.Server.Documents.Replication.ReplicationLoader.AcceptIncomingConnection(TcpConnectionOptions tcpConnectionOptions, ManagedPinnedBuffer buffer) in F:\ravendb-4.0\src\Raven.Server\Documents\Replication\ReplicationLoader.cs:line 248
   at Raven.Server.RavenServer.DispatchDatabaseTcpConnection(TcpConnectionOptions tcp, TcpConnectionHeaderMessage header, ManagedPinnedBuffer bufferToCopy) in F:\ravendb-4.0\src\Raven.Server\RavenServer.cs:line 1469
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[TStateMachine](TStateMachine& stateMachine)
   at Raven.Server.RavenServer.DispatchDatabaseTcpConnection(TcpConnectionOptions tcp, TcpConnectionHeaderMessage header, ManagedPinnedBuffer bufferToCopy)
   at Raven.Server.RavenServer.<>c__DisplayClass46_0.<<ListenToNewTcpConnection>b__0>d.MoveNext() in F:\ravendb-4.0\src\Raven.Server\RavenServer.cs:line 1289
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext()
   at System.Runtime.CompilerServices.TaskAwaiter.<>c.<OutputWaitEtwEvents>b__12_0(Action innerContinuation, Task innerTask)
   at System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(Action action, Boolean allowInlining)
   at System.Threading.Tasks.Task.RunContinuations(Object continuationObject)
   at System.Threading.Tasks.Task`1.TrySetResult(TResult result)
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.SetExistingTaskResult(TResult result)
   at Sparrow.Json.JsonOperationContext.ParseToMemoryAsync(Stream stream, String documentId, UsageMode mode, ManagedPinnedBuffer bytes, Nullable`1 token, Int32 maxSize) in F:\ravendb-4.0\src\Sparrow\Json\JsonOperationContext.cs:line 942
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1.AsyncStateMachineBox`1.MoveNext()
   at System.Runtime.CompilerServices.TaskAwaiter.<>c.<OutputWaitEtwEvents>b__12_0(Action innerContinuation, Task innerTask)
   at System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(Action action, Boolean allowInlining)
   at System.Threading.Tasks.Task.RunContinuations(Object continuationObject)
   at System.Threading.Tasks.Task`1.TrySetResult(TResult result)
   at System.Threading.Tasks.ValueTask`1.ValueTaskSourceAsTask.<>c.<.cctor>b__4_0(Object state)
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.InvokeContinuation(Action`1 continuation, Object state, Boolean forceAsync)
   at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.OnCompleted(SocketAsyncEventArgs _)
   at System.Net.Sockets.SocketAsyncEventArgs.FinishOperationAsyncSuccess(Int32 bytesTransferred, SocketFlags flags)
   at System.Net.Sockets.SocketAsyncEventArgs.<>c.<.cctor>b__177_0(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* nativeOverlapped)
   at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)

Could not load file or assembly 'Ben.Demystifier, Version=0.1.0.0 ...

Attempting to use Ben.Demystifier version 0.1.4 installed via NuGet. I am getting the following error at runtime.

Looks like the version number is not getting set correctly?

Could not load file or assembly 'Ben.Demystifier, Version=0.1.0.0, Culture=neutral, PublicKeyToken=a6d206e05440431a' or one of its dependencies. The system cannot find the file specified.

Aggregate exceptions

Great library! Biggest problem with doing good work is people raise awkward questions! Sorry.

What's the best way to handle AggregateExceptions? I'm using Service Fabric and Serilog for all my logging. Lots of cross service exceptions are exposed as AggregateExceptions and they still produce a generally old fashioned stack trace.

I've got something working by just logging the inner exception, but that seems like I'm handling the problem at the wrong level. I think Demystify should handle the aggregate exception internally.

This change in Demystify may work - does it make sense?

                if (exception is AggregateException aex)
                {
                    foreach (var innerException in aex.InnerExceptions)
                    {
                        innerException.Demystify();
                    }
                }
                else
                {
                    exception.InnerException?.Demystify();
                }

Any plans for .NET Native support (UWP in RELEASE mode)?

Hello Ben, I've started using this lib and I have to say so far it's great, you did an awesome job here!
I did some tests with the UWP framework and it looks like the Demistify method fails when the app is compiled in RELEASE mode, ie. when the .NET Native toolchain is enabled.

Here's a simple screen, you can see both the stack traces are the same (the first one is the original, the second is the one extracted after calling Demistify):
image

Are there any plans to support the .NET Native compiler in the future, and is that possible in the first place?

Cheers!
Sergio

The PDB reader occasionally fails with file access exception

System.IO.IOException: The process cannot access the file 'C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\6dac5fe0\f282cd8a\assembly\dl3\5032d4d4\5885728e_c5e2d301\WebApp.Compiled.pdb' because it is being used by another process.
void System.IO.__Error.WinIOError(int errorCode, string maybeFullPath)
void System.IO.FileStream.Init(string path, FileMode mode, FileAccess access, int rights, bool useRights, FileShare share, int bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, string msgPath, bool bFromProxy, bool useLongPath, bool checkHost)
new System.IO.FileStream(string path, FileMode mode, FileAccess access, FileShare share)
bool System.Diagnostics.Internal.PortablePdbReader.IsPortable(string pdbPath)
MetadataReader System.Diagnostics.Internal.PortablePdbReader.GetMetadataReader(string assemblyPath)
void System.Diagnostics.Internal.PortablePdbReader.PopulateStackFrame(StackFrame frameInfo, MethodBase method, int IlOffset, out string fileName, out int row, out int column)
List<EnhancedStackFrame> System.Diagnostics.EnhancedStackTrace.GetFrames(StackTrace stackTrace)
new System.Diagnostics.EnhancedStackTrace(StackTrace stackTrace)
...

I checked the code for PortablePdbReader and it seems that it opens the files with proper sharing mode (via File.OpenRead), so I have no idea why it can fail or who else could be opening the PDB (this is an ASP.NET 4.5 application running in IIS 8), but I believe I still have to report this.
I'm going to place an IOException handler around calls to the Demystifier methods in our code to handle cases like these, and I think you could consider doing the same.

Stack trace for generic types with tuples is incorrect

Here is an example:

async Task<(int left, int right)> AsyncThatReturnsTuple()
{
        await Task.Delay(1).ConfigureAwait(false);
        throw new ArgumentException();
}

In this case the demystified exception looks like this:

at async (ValueTuple<int, int> left) ConsoleApp11.Program.AsyncWithTuple() 

But should be

at async Task<(int left, int right)> ConsoleApp11.Program.AsyncWithTuple() 

GetParameter throws on Task<object> on GetCustomAttributes<TupleElementNamesAttribute>

var tupleNames = parameter.GetCustomAttributes<TupleElementNamesAttribute>().FirstOrDefault()?.TransformNames;

Throws an index of out range exception when there are no custom attributes.

Specific type where I saw it was

System.Threading.Tasks.Task`1[[System.Object, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

Running on .NET 4.6.2

Assembly version is missing build and revision numbers

Version 0.0.43 is missing assembly version. When this assembly is references in csproj, it shows as

<Reference Include="Ben.Demystifier, Version=0.0.0.0, Culture=neutral, PublicKeyToken=a6d206e05440431a, processorArchitecture=MSIL">
  <HintPath>..\packages\Ben.Demystifier.0.0.43\lib\net45\Ben.Demystifier.dll</HintPath>
</Reference>

Version 0.0.8 shows as

<Reference Include="Ben.Demystifier, Version=0.0.8.0, Culture=neutral, processorArchitecture=MSIL">
  <HintPath>..\packages\Ben.Demystifier.0.0.8\lib\net45\Ben.Demystifier.dll</HintPath>
</Reference>

While this is not a problem by itself. It does cause breakage in any libraries that depend on Ben.Demystifier.

For example, if codeessentials.Extensions.Logging.Demystifier is installed, it works fine with 0.0.8 ,but loading exception is thrown for 0.0.43 :

Could not load file or assembly 'Ben.Demystifier, Version=0.0.4.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

Add ValueTask support

https://github.com/benaadams/Ben.Demystifier/blob/master/src/Ben.Demystifier/EnhancedStackTrace.Frames.cs#L686

                else if (type == typeof(TaskAwaiter) ||
                    type == typeof(TaskAwaiter<>) ||
+                   type == typeof(ValueTaskAwaiter) ||
+                   type == typeof(ValueTaskAwaiter<>) ||
+                   type == typeof(ConfiguredValueTaskAwaitable.ConfiguredValueTaskAwaiter) ||
+                   type == typeof(ConfiguredValueTaskAwaitable<>.ConfiguredValueTaskAwaiter) ||
                    type == typeof(ConfiguredTaskAwaitable.ConfiguredTaskAwaiter) ||
                    type == typeof(ConfiguredTaskAwaitable<>.ConfiguredTaskAwaiter))
                {

https://github.com/benaadams/Ben.Demystifier/blob/master/src/Ben.Demystifier/Ben.Demystifier.csproj#L17

  <PropertyGroup>
-   <TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
+   <TargetFrameworks>netstandard2.1;netstandard2.0;net45</TargetFrameworks>
  </PropertyGroup>

  <ItemGroup>
+   <PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.2" Condition="'$(TargetFramework)' != 'netstandard2.1'" />
  </ItemGroup>

EnhancedStackTrace fails on exceptions without stack trace

When I have an exception that was not thrown, it does not have any stack trace (null is in StackTrace) and EnhancedStackTrace fails on that. It kind of makes sense, as there is no stack trace, but I think it would be nicer if would return an empty list or propagate the null.

The problem is that this error check returns null from GetFrames and later it throws NullReferenceException on all places that touch _frames. I think that it would better to return an empty list in these cases.

Missing Assemblies because of System.ValueTuple?

Probably not a bug, but maybe a good thing to put in readme?
I installed this on a net 461 project yesterday. We ran into weird problems, for example a referenced project couldnt find System.Net.Http 4.2.0.0.

I thought maybe net462 was needed so we tried to upgrade. Still the asme problem.

Tried to Run Add-BindingRedirect etc.
Tried upgrading all the way to net471.

Never got it to run. If I removed Ben.Demystifier it all worked again.

Any clues on how to resolve this?

Strong-Naming the assembly

What are the odds of you strong-naming the assembly anytime soon?

I can get around it by repackaging the nuget, but I would rather use yours directly so I can pull updates easily.

IndexOutOfRangeException in ILReader.ReadOpCode() line 36

When analyzing a certain exception I'm seeing an exception in ILReader.ReadOpCode() line 36 here:

return singleByteOpCode[instruction];

The instruction is 235. singleByteOpCode only contains 225 entries.

Stack trace:

>	System.Diagnostics.Internal.ILReader.ReadOpCode Line 36	C#	Symbols loaded.
 	System.Diagnostics.Internal.ILReader.Read Line 25	C#	Symbols loaded.
 	System.Diagnostics.EnhancedStackTrace.TryResolveSourceMethod Line 350	C#	Symbols loaded.
 	System.Diagnostics.EnhancedStackTrace.TryResolveGeneratedName Line 289	C#	Symbols loaded.
 	System.Diagnostics.EnhancedStackTrace.GetMethodDisplayString Line 122	C#	Symbols loaded.
 	System.Diagnostics.EnhancedStackTrace.GetFrames Line 71	C#	Symbols loaded.
 	System.Diagnostics.EnhancedStackTrace.EnhancedStackTrace Line 46	C#	Symbols loaded.

Expose cleaned up Exception

Right now when an exception is .Demystify() it exposes a cleaned up stack trace.
The issue is, I'm using Bugsnag (probably not the only library) that takes the exception and builds some internal structure (StackTraceLine - https://github.com/bugsnag/bugsnag-dotnet/blob/96360fb0f8d31f5fd6a8f3f17184bd626421820e/src/Bugsnag/Payload/Exception.cs#L85) before logging it. Therefore, the Demystifier has no effect.

Can we please get a Demystify() that cleans up the stack frames as well so that if the exception is used in another library it will not include the unnecessary stack frames?

System.Runtime.InteropServices.COMException being very annoying!

Got some hairy service fabric traces that contain a number of COMExceptions.

Unfortunately it looks like the stack trace for this can't be cleaned up.

Here's a subset of the stack trace!

System.Runtime.InteropServices.COMException (0x80071BCD): Exception from HRESULT: 0x80071BCD
   at System.Fabric.Interop.NativeClient.IFabricServiceManagementClient6.EndResolveServicePartition(IFabricAsyncOperationContext context)
   at System.Fabric.FabricClient.ServiceManagementClient.ResolveServicePartitionEndWrapper(IFabricAsyncOperationContext context)
   at System.Fabric.Interop.AsyncCallOutAdapter2`1.Finish(IFabricAsyncOperationContext context, Boolean expectedCompletedSynchronously)

What appears to be happening is that in EnhancedStackTrace.GetFrames(Exception) a new StackTrace is constructed from the exception, but that stack trace is empty. I think this is because the _stackTrace field is null, whilst the _stackTraceString field contains the string representation.

So at the moment I don't think anything can be easily done, however it may be worth while putting something in the documentation saying that there are some exceptions that can't be cleaned.

.Net4.0 Support

Hi,
It would be great if this package target .net4.0 as it is the last Long Term release and heavily deployed. Also, it would be great if Demystifier can work in StackTrace string as that would really much increase its usability even in CI Servers to post-process data.

Thanks for this great package

Incorrect paths are constructed for source locations when compiled on Windows but run on !Windows

When running a program that I compiled on Windows (standalone .NET Core app, compiled via dotnet publish -o foo -c Release -r ubuntu16.04-arm for a RPi), I get demystified stack traces that have the absolute Windows paths from the PDBs appended to the current working directory of the app on Linux:

System.FormatException: Input string was not in a correct format.
     at float Number.ParseSingle(string value, NumberStyles options, NumberFormatInfo numfmt)
     at BellowsRecord ZigBeeGrapher.Program+BellowsRecord.Parse(string line) in /home/pi/zigbee-grapher/C:\Users\BojanRajkovic\source\repos\ZigBeeGrapher\Program.cs:line 351
     at async Task ZigBeeGrapher.Program.ProcessCsvLinesAsync(IList<string> csvLines) in /home/pi/zigbee-grapher/C:\Users\BojanRajkovic\source\repos\ZigBeeGrapher\Program.cs:line 90

I haven't explored a whole ton, but I suspect there's some absolute path detection that isn't considering this scenario.

Edit: Looks like this code is the culprit: https://github.com/benaadams/Ben.Demystifier/blob/master/src/Ben.Demystifier/EnhancedStackTrace.cs#L110.

NuGet package adds duplicate references

I would like to use this, but somehow installing the NuGet package adds a lot of duplicate references to my projects for system packages such as System.Collections, System.ComponentModel, etc.

Using .NET Framework 4.6.2 in my projects. For example, the System.Collections package referenced is:

System.Collections, Version=4.0.10.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.2\Facades\System.Collections.dll

Installing the Demystifier NuGet package adds the duplicate reference:

System.Collections, Version=4.0.11.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a C:\Program Files (x86)\MSBuild\Microsoft\Microsoft.NET.Build.Extensions\net461\ref\System.Collections.dll

Anything I can do about that?

Add extension to demystify StackTrace

In some cases we're logging stack traces using new StackTrace() and it would be nice to have an extension that would demystify the StackTrace alone. For now I've hacked it internally by using new EnhancedStackTrace(new StackTrace()) but maybe such extension method would be useful for others as well? If you think it's a good idea I can prepare a PR for it.

Some System.Web.Mvc DisplayName methods unresolved

I have a stacktrace line that, after prettifying looks like this:

at void System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass21+<>c__DisplayClass2b.<BeginInvokeAction>b__1c(?)+()=>{}

It looks like it can't find a pdb file for System.Web.Mvc, which resides in the Temporary ASP.NET directory. Could that have something to do with it (and is there anything I can do to make the/a pdb available)?

Is this expected output or could this be prettified further?

Consider removing asp.net middleware frames

Heres a segment of our stack trace. Note our relevant lines (labelled RiskFabricator) have 10 lines of AspNetCore internals in between.

at async Task RiskFabricator.Controllers.GetRiskController.Get(string product, string version, string base64EnquiryId, CancellationToken cancellationToken) in /build/src/RiskFabricator/Controllers/GetRiskController.cs:line 27
at async Task Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()
at async Task Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()
at void Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
at Task Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
at async Task Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
at async Task Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
at void Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
at Task Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
at async Task Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
at async Task Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
at async Task Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
at async Task RiskFabricator.HeaderExtractionMiddleware.ExtractEmailHashInformationMiddleware.Invoke(HttpContext context) in /build/src/RiskFabricator/HeaderExtractionMiddleware/ExtractEmailHashInformationMiddleware.cs:line 27

Local function with method invocation on variable from outer scope

I have discovered erroneous behavior with local function. Here a small app to reproduce:

internal class Program
{
    private static async Task Main(string[] args)
    {
        int number = default;
        try
        {
            await Fun();
            
            async Task Fun()
            {
                number.ToString();
                throw new Exception();
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Demystify());
        }
}

Execution of the code above produces following stack trace:

System.Exception: Exception of type 'System.Exception' was thrown.
   at void Program+<>c__DisplayClass0_0+<<Main>g__Fun|0>d.MoveNext()
   at async Task Program.Main(string[] args)

If I remove number.ToString(); it produces expected stack trace.

Add source to the repo

Please provide the source in this repository. Looking at the readme, this thing would be really valuable to already use. Good stuff building this ๐Ÿฅ‡ .

I can imagine that this is still very much in flux, and rough around the edges, but this thing would already be a great help to understand some weird stacktraces that I see every day. So I would be fine with something that not really finished yet (I'll get it to work).

If there could be a way for already using this, I'd greatly appreciate it. ๐ŸŽ‰

Error: Index was outside the bounds of the array.

I just saw this on my logs:

23-11-2017 19:49:53:782: [Error ] ProcessRequestAsync IndexOutOfRangeException: Message: Index was outside the bounds of the array. Stack trace: at ParameterInfo Attribute.GetParentDefinition(ParameterInfo param) at Attribute[] Attribute.InternalParamGetCustomAttributes(ParameterInfo param, Type type, bool inherit) at IEnumerable<T> System.Reflection.CustomAttributeExtensions.GetCustomAttributes<T>(ParameterInfo element) at ResolvedParameter System.Diagnostics.EnhancedStackTrace.GetParameter(ParameterInfo parameter) at ResolvedMethod System.Diagnostics.EnhancedStackTrace.GetMethodDisplayString(MethodBase originMethod) at List<EnhancedStackFrame> System.Diagnostics.EnhancedStackTrace.GetFrames(StackTrace stackTrace) at List<EnhancedStackFrame> System.Diagnostics.EnhancedStackTrace.GetFrames(Exception exception) at new System.Diagnostics.EnhancedStackTrace(Exception e) at new DDS.Runtime.Diagnostics.Data.Details.ExceptionDetailBuilder(Exception exception) at ILogEntry DDS.Runtime.Diagnostics.Logger.Write(LogEventType eventType, string message, Exception exception, LogEntryData data) at ILogEntry DDS.Runtime.Diagnostics.Primitives.DiagnosticsPrimitivesExtensions.LogError(ILogger logger, Exception exception, LogEntryData data) at void DDS.AspNetCore.Mvc.Filters.StatusExceptionFilter.OnException(ExceptionContext context) at Task Microsoft.AspNetCore.Mvc.Filters.ExceptionFilterAttribute.OnExceptionAsync(ExceptionContext context) at Task Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted) at async Task Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter() at void Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context) at Task Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted) at async Task Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync() at async Task Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync() at async Task Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext) at async Task Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context) at async Task Microsoft.AspNetCore.Session.SessionMiddleware.Invoke(HttpContext context) at async Task Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) at async Task Microsoft.AspNetCore.ResponseCompression.ResponseCompressionMiddleware.Invoke(HttpContext context) at async Task Microsoft.AspNetCore.Hosting.Internal.RequestServicesContainerMiddleware.Invoke(HttpContext httpContext) at async void Microsoft.AspNetCore.Server.HttpSys.MessagePump.ProcessRequestAsync(object requestContextObj) at async void Microsoft.AspNetCore.Server.HttpSys.MessagePump.ProcessRequestAsync(object requestContextObj)

Not sure what the original error was.... I'm trying to reproduce locally and post any additional information...

Support .NET 4.5

The nugget package target .NET4.6 which mean we can't use it on our .NET4.5 projects.
Thanks you for the greatness !!

Full type name for method parameters

Type name for a method parameter should include the corresponding namespace if the type is a non-BCL type.

Example:

namespace n
{
    class t
    {
        public void m(object p0, n1.t1 p1) => m(null, null as n2.t1);
        public void m(object p0, n2.t1 p1) => throw new Exception();
    }
}

namespace n1
{
    class t1 { }
}

namespace n2
{
    class t1 { }
}

new n.t().m(null, null as n1.t1)

Current behavior

void n.t.m(object p0, t1 p1)
void n.t.m(object p0, t1 p1)

Expected behavior:

void n.t.m(object p0, n2.t1 p1)
void n.t.m(object p0, n1.t1 p1)

ToStringDemystified() doesn't use the standard ToString() pattern for inner exceptions

Consider the following LINQPad code:

void Main()
{
	try { Foo(); }
	catch (Exception e)
	{
		e.ToString().Dump("ToString");
		e.ToStringDemystified().Dump("ToStringDemystified");
		e.Demystify().ToString().Dump(".Demystify().ToString()");
	}
}

public void Foo()
{
	try { Bar();} catch(Exception e) {throw new InvalidOperationException("Something failed while trying to Bar", e);}
}
public void Bar()
{
	try { Baz(); } catch (Exception e) { throw new InvalidOperationException("Something failed while trying to Baz", e); }
}
public void Baz()
{
	throw new InvalidOperationException("Something went wrong in here");
}

Output for .Demystify().ToString() looks like this:

System.InvalidOperationException: Something failed while trying to Bar ---> System.InvalidOperationException: Something failed while trying to Baz ---> System.InvalidOperationException: Something went wrong in here
   at void UserQuery.Bar() in C:/Users/james.jensen/AppData/Local/Temp/LINQPad5/_pwdvguda/query_wparci.cs:line 47
   --- End of inner exception stack trace ---
   at void UserQuery.Bar() in C:/Users/james.jensen/AppData/Local/Temp/LINQPad5/_pwdvguda/query_wparci.cs:line 47
   at void UserQuery.Foo() in C:/Users/james.jensen/AppData/Local/Temp/LINQPad5/_pwdvguda/query_wparci.cs:line 43
   --- End of inner exception stack trace ---
   at void UserQuery.Foo() in C:/Users/james.jensen/AppData/Local/Temp/LINQPad5/_pwdvguda/query_wparci.cs:line 43
   at void UserQuery.Main() in C:/Users/james.jensen/AppData/Local/Temp/LINQPad5/_pwdvguda/query_wparci.cs:line 31

Output for .ToStringDemystified() looks like this:

System.InvalidOperationException: Something failed while trying to Bar
   at void UserQuery.Foo() in C:/Users/james.jensen/AppData/Local/Temp/LINQPad5/_pwdvguda/query_wparci.cs:line 43
   at void UserQuery.Main() in C:/Users/james.jensen/AppData/Local/Temp/LINQPad5/_pwdvguda/query_wparci.cs:line 31 ---> System.InvalidOperationException: Something failed while trying to Baz
   at void UserQuery.Bar() in C:/Users/james.jensen/AppData/Local/Temp/LINQPad5/_pwdvguda/query_wparci.cs:line 47
   at void UserQuery.Foo() in C:/Users/james.jensen/AppData/Local/Temp/LINQPad5/_pwdvguda/query_wparci.cs:line 43 ---> System.InvalidOperationException: Something went wrong in here
   at void UserQuery.Bar() in C:/Users/james.jensen/AppData/Local/Temp/LINQPad5/_pwdvguda/query_wparci.cs:line 47
   --- End of inner exception stack trace ---
   --- End of inner exception stack trace ---

I believe this changed in a recent patch version update. (Tested on 0.1.4)

GetMethodDisplayString incorrectly decodes nested lambda

I'm using EnhancedStackTrace.GetMethodDisplayString on its own to decode the name of a lambda nested in another lambda, but the result is not correct.

Specifically, it reproduces with this code:

using System;
using System.Diagnostics;

class Program
{
    static void Main()
    {
        void Execute(Action a) => a();

        Execute(() =>
        {
            Action b = () => {};

            Console.WriteLine(EnhancedStackTrace.GetMethodDisplayString(b.Method));
        });
    }
}

This prints void Program+<>c.<Main>b__0_2(?)+() => { }, which still looks mystifying.

This code decompiles to:

internal class Program
{
    [CompilerGenerated]
    [Serializable]
    private sealed class <>c
    {
        public static readonly Program.<>c <>9 = new Program.<>c();

        public static Action <>9__0_2;

        public static Action <>9__0_1;

        internal void <Main>b__0_1()
        {
            Action arg_1F_0;
            if ((arg_1F_0 = Program.<>c.<>9__0_2) == null)
            {
                Program.<>c.<>9__0_2 = (arg_1F_0 = new Action(Program.<>c.<>9.<Main>b__0_2));
            }
            Console.WriteLine(EnhancedStackTrace.GetMethodDisplayString(arg_1F_0.Method));
        }

        internal void <Main>b__0_2()
        {
        }
    }

    private static void Main()
    {
        Action arg_1F_0;
        if ((arg_1F_0 = Program.<>c.<>9__0_1) == null)
        {
            Program.<>c.<>9__0_1 = (arg_1F_0 = new Action(Program.<>c.<>9.<Main>b__0_1));
        }
        Program.<Main>g__Execute0_0(arg_1F_0);
    }

    [CompilerGenerated]
    internal static void <Main>g__Execute0_0(Action a)
    {
        a();
    }
}

Error parsing stack trace (in ILReader.ReadOpCode)

I'm getting the following error in my logs:

IndexOutOfRangeException:
Message: Index was outside the bounds of the array.
Stack trace:
	at OpCode System.Diagnostics.Internal.ILReader.ReadOpCode()
	at bool System.Diagnostics.Internal.ILReader.Read(MethodBase methodInfo)
	at bool System.Diagnostics.EnhancedStackTrace.TryResolveSourceMethod(IEnumerable<MethodBase> candidateMethods, GeneratedNameKind kind, string matchHint, ref MethodBase method, ref Type type, out Nullable<int> ordinal)
	at bool System.Diagnostics.EnhancedStackTrace.TryResolveGeneratedName(ref MethodBase method, out Type type, out string methodName, out string subMethodName, out GeneratedNameKind kind, out Nullable<int> ordinal)
	at ResolvedMethod System.Diagnostics.EnhancedStackTrace.GetMethodDisplayString(MethodBase originMethod)
	at List<EnhancedStackFrame> System.Diagnostics.EnhancedStackTrace.GetFrames(StackTrace stackTrace)
	at List<EnhancedStackFrame> System.Diagnostics.EnhancedStackTrace.GetFrames(Exception exception)
	at new System.Diagnostics.EnhancedStackTrace(Exception e)
	at new DDS.Runtime.Diagnostics.Data.Details.ExceptionDetailBuilder(Exception exception)

Since I'm catching possible errors in Demystifier, when this happens, I store the original stack trace unmodified, so the above error was related to this stack trace:

Message: Unable to connect to any of the specified MySQL hosts.
Stack trace:
	   at MySqlConnector.Core.ServerSession.<ConnectAsync>d__56.MoveNext() in C:\projects\mysqlconnector\src\MySqlConnector\Core\ServerSession.cs:line 215
	--- End of stack trace from previous location where exception was thrown ---
	   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
	   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
	   at MySql.Data.MySqlClient.MySqlConnection.<CreateSessionAsync>d__77.MoveNext() in C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlConnection.cs:line 365
	--- End of stack trace from previous location where exception was thrown ---
	   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
	   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
	   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
	   at MySql.Data.MySqlClient.MySqlConnection.<OpenAsync>d__19.MoveNext() in C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlConnection.cs:line 160
	--- End of stack trace from previous location where exception was thrown ---
	   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
	   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
	   at MySql.Data.MySqlClient.MySqlConnection.Open() in C:\projects\mysqlconnector\src\MySqlConnector\MySql.Data.MySqlClient\MySqlConnection.cs:line 137
	   at Microsoft.EntityFrameworkCore.Storage.Internal.MySqlConnectionSettings.<>c__DisplayClass2_0.<GetSettings>b__0(String key)
	   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
	   at Microsoft.EntityFrameworkCore.Storage.Internal.MySqlConnectionSettings.GetSettings(String connectionString)
	   at Microsoft.EntityFrameworkCore.Internal.MySqlOptions.<.ctor>b__2_0()
	   at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
	--- End of stack trace from previous location where exception was thrown ---
	   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
	   at System.Lazy`1.CreateValue()
	   at Microsoft.EntityFrameworkCore.Internal.MySqlOptions.get_ConnectionSettings()
	   at Microsoft.EntityFrameworkCore.Storage.Internal.MySqlSmartTypeMapper.MaybeConvertMapping(RelationalTypeMapping mapping)
	   at Microsoft.EntityFrameworkCore.Storage.Internal.MySqlSmartTypeMapper.FindMapping(Type clrType)
	   at Microsoft.EntityFrameworkCore.Storage.RelationalTypeMapper.IsTypeMapped(Type clrType)
	   at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.PropertyDiscoveryConvention.IsCandidatePrimitiveProperty(PropertyInfo propertyInfo)
	   at System.Linq.Enumerable.WhereArrayIterator`1.MoveNext()
	   at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.PropertyDiscoveryConvention.Apply(InternalEntityTypeBuilder entityTypeBuilder)
	   at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.ImmediateConventionScope.OnEntityTypeAdded(InternalEntityTypeBuilder entityTypeBuilder)
	   at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.OnEntityTypeAdded(InternalEntityTypeBuilder entityTypeBuilder)
	   at Microsoft.EntityFrameworkCore.Metadata.Internal.Model.AddEntityType(EntityType entityType)
	   at Microsoft.EntityFrameworkCore.Metadata.Internal.Model.AddEntityType(Type type, ConfigurationSource configurationSource)
	   at Microsoft.EntityFrameworkCore.Metadata.Internal.InternalModelBuilder.Entity(TypeIdentity type, ConfigurationSource configurationSource)
	   at Microsoft.EntityFrameworkCore.Metadata.Internal.InternalModelBuilder.Entity(Type type, ConfigurationSource configurationSource)
	   at Microsoft.EntityFrameworkCore.ModelBuilder.Entity(Type type)
	   at Microsoft.EntityFrameworkCore.Infrastructure.ModelCustomizer.FindSets(ModelBuilder modelBuilder, DbContext context)
	   at Microsoft.EntityFrameworkCore.Infrastructure.RelationalModelCustomizer.FindSets(ModelBuilder modelBuilder, DbContext context)
	   at Microsoft.EntityFrameworkCore.Infrastructure.ModelCustomizer.Customize(ModelBuilder modelBuilder, DbContext context)
	   at Microsoft.EntityFrameworkCore.Infrastructure.RelationalModelCustomizer.Customize(ModelBuilder modelBuilder, DbContext context)
	   at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext context, IConventionSetBuilder conventionSetBuilder, IModelValidator validator)
	   at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.<>c__DisplayClass5_0.<GetModel>b__0(Object k)
	   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
	   at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.GetModel(DbContext context, IConventionSetBuilder conventionSetBuilder, IModelValidator validator)
	   at Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel()
	   at Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model()
	   at Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServicesBuilder.<>c.<TryAddCoreServices>b__7_1(IServiceProvider p)
	   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, ServiceProvider provider)
	   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
	   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider)
	   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
	   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProvider provider)
	   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
	   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider)
	   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
	   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(IServiceCallSite callSite, ServiceProvider provider)
	   at Microsoft.Extensions.DependencyInjection.ServiceProvider.<>c__DisplayClass22_0.<RealizeService>b__0(ServiceProvider provider)
	   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)
	   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider)
	   at Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServicesBuilder.<>c.<TryAddCoreServices>b__7_10(IServiceProvider p)
	   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, ServiceProvider provider)
	   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
	   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider)
	   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
	   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitIEnumerable(IEnumerableCallSite enumerableCallSite, ServiceProvider provider)
	   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
	   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(IServiceCallSite callSite, ServiceProvider provider)
	   at Microsoft.Extensions.DependencyInjection.ServiceProvider.<>c__DisplayClass22_0.<RealizeService>b__0(ServiceProvider provider)
	   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)
	   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider)
	   at Microsoft.EntityFrameworkCore.DbContext.Microsoft.EntityFrameworkCore.Internal.IDbContextPoolable.ResetState()
	   at Microsoft.EntityFrameworkCore.Internal.DbContextPool`1.Return(TContext context)
	   at Microsoft.EntityFrameworkCore.Internal.DbContextPool`1.Microsoft.EntityFrameworkCore.Internal.IDbContextPool.Return(DbContext context)
	   at Microsoft.EntityFrameworkCore.DbContext.Dispose()
	   at Microsoft.Extensions.DependencyInjection.ServiceProvider.Dispose()
	   at Microsoft.AspNetCore.Hosting.Internal.WebHost.Dispose()

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.