public void StackTraceHelper_ProducesReadableOutput() { // Arrange var expectedCallStack = new List <string>() { "Microsoft.Extensions.Internal.StackTraceHelperTest.Iterator()+MoveNext()", "string.Join(string separator, IEnumerable<string> values)", "Microsoft.Extensions.Internal.StackTraceHelperTest+GenericClass<T>.GenericMethod<V>(ref V value)", "Microsoft.Extensions.Internal.StackTraceHelperTest.MethodAsync(int value)", "Microsoft.Extensions.Internal.StackTraceHelperTest.MethodAsync<TValue>(TValue value)", "Microsoft.Extensions.Internal.StackTraceHelperTest.Method(string value)", "Microsoft.Extensions.Internal.StackTraceHelperTest.StackTraceHelper_ProducesReadableOutput()", }; Exception exception = null; try { Method("test"); } catch (Exception ex) { exception = ex; } // Act var stackFrames = StackTraceHelper.GetFrames(exception, out _); var methodNames = stackFrames.Select(stackFrame => stackFrame.MethodDisplayInfo.ToString()).ToArray(); // Assert Assert.Equal(expectedCallStack, methodNames); }
public void StackTraceHelper_IncludesLineNumbersForFiles() { // Arrange Exception exception = null; try { // Throwing an exception in the current assembly always seems to populate the full stack // trace regardless of symbol type. Crossing assembly boundaries ensures PortablePdbReader gets used // on desktop. Thrower.Throw(); } catch (Exception ex) { exception = ex; } // Act var stackFrames = StackTraceHelper.GetFrames(exception); // Assert Assert.Collection(stackFrames, frame => { Assert.Contains("Thrower.cs", frame.FilePath); Assert.Equal(17, frame.LineNumber); }, frame => { Assert.Contains("StackTraceHelperTest.cs", frame.FilePath); }); }
public void StackTraceHelper_PrettyPrintsStackTraceForMethodsWithGenericOutParameters() { // Arrange var exception = Record.Exception(() => MethodWithGenericOutParameter("Test", out int value)); // Act var stackFrames = StackTraceHelper.GetFrames(exception, out _); // Assert var methods = stackFrames.Select(frame => frame.MethodDisplayInfo.ToString()).ToArray(); Assert.Equal("Microsoft.Extensions.Internal.StackTraceHelperTest.MethodWithGenericOutParameter<TVal>(string a, out TVal value)", methods[0]); }
public void StackTraceHelper_PrettyPrintsStackTraceForGenericMethods() { // Arrange var exception = Record.Exception(() => GenericMethod <string>(null)); // Act var stackFrames = StackTraceHelper.GetFrames(exception, out _); // Assert var methods = stackFrames.Select(frame => frame.MethodDisplayInfo.ToString()).ToArray(); Assert.Equal("Microsoft.Extensions.Internal.StackTraceHelperTest.GenericMethod<T>(T val)", methods[0]); }
public void StackTraceHelper_PrettyPrintsStackTraceForMethodsOnGenericTypes() { // Arrange var exception = Record.Exception(() => new GenericClass <int>().Throw(0)); // Act var stackFrames = StackTraceHelper.GetFrames(exception, out _); // Assert var methods = stackFrames.Select(frame => frame.MethodDisplayInfo.ToString()).ToArray(); Assert.Equal("Microsoft.Extensions.Internal.StackTraceHelperTest+GenericClass<T>.Throw(T parameter)", methods[0]); }
public void StackTraceHelper_DoesNotIncludeMethodsWithStackTraceHiddenAttribute() { // Arrange var exception = Record.Exception(() => new TypeWithMethodWithStackTraceHiddenAttribute().Throw()); // Act var stackFrames = StackTraceHelper.GetFrames(exception, out _); // Assert var methods = stackFrames.Select(frame => frame.MethodDisplayInfo.ToString()).ToArray(); Assert.Equal("Microsoft.Extensions.Internal.StackTraceHelperTest.ThrowCore()", methods[0]); Assert.Equal("Microsoft.Extensions.Internal.StackTraceHelperTest+TypeWithMethodWithStackTraceHiddenAttribute.Throw()", methods[1]); }
private IEnumerable <ErrorDetails> GetErrorDetails(Exception ex) { for (var scan = ex; scan != null; scan = scan.InnerException) { var stackTrace = ex.StackTrace; yield return(new ErrorDetails { Error = scan, StackFrames = StackTraceHelper.GetFrames(ex) .Select(frame => GetStackFrame(frame.Method, frame.FilePath, frame.LineNumber)) }); } ; }
public void StackTraceHelper_PrettyPrintsStackTraceForMethodsWithNullableParameters() { // Arrange var value = 0; var exception = Record.Exception(() => MethodWithNullableParameter(value)); // Act var stackFrames = StackTraceHelper.GetFrames(exception, out _); // Assert var methods = stackFrames.Select(frame => frame.MethodDisplayInfo.ToString()).ToArray(); Assert.Equal("Microsoft.Extensions.Internal.StackTraceHelperTest.MethodWithNullableParameter(Nullable<int> value)", methods[0]); }
private IEnumerable <StackFrameSourceCodeInfo> GetStackFrames(Exception original) { var stackFrames = StackTraceHelper.GetFrames(original, out var exception) .Select(frame => GetStackFrameSourceCodeInfo( frame.MethodDisplayInfo?.ToString(), frame.FilePath, frame.LineNumber)); if (exception != null) { _logger?.FailedToReadStackTraceInfo(exception); } return(stackFrames); }
public void GetFrames_CanGetStackTrace(Action action, string expectedMethodName) { try { action(); } catch (Exception exception) { // Arrange and Act var frames = StackTraceHelper.GetFrames(exception); // Assert Assert.Equal(expectedMethodName, frames.First().Method); Assert.Equal(nameof(GetFrames_CanGetStackTrace), frames.Last().Method); } }
public void GetFrames_DoesNotFailForDynamicallyGeneratedAssemblies() { // Arrange var action = (Action)Expression.Lambda( Expression.Throw( Expression.New(typeof(Exception)))).Compile(); var exception = Record.Exception(action); // Act var frames = StackTraceHelper.GetFrames(exception).ToArray(); // Assert var frame = frames[0]; Assert.Null(frame.FilePath); Assert.Equal($"lambda_method(Closure )", frame.MethodDisplayInfo.ToString()); }
public void GetFrames_CanGetStackTrace(Action action, string expectedDisplay) { try { action(); } catch (Exception exception) { // Arrange and Act var frames = StackTraceHelper.GetFrames(exception); // Assert Assert.Equal(expectedDisplay, frames.First().MethodDisplayInfo.ToString()); Assert.Equal( $"{typeof(StackTraceTest).GetTypeInfo().FullName}.{nameof(GetFrames_CanGetStackTrace)}" + "(Action action, string expectedDisplay)", frames.Last().MethodDisplayInfo.ToString()); } }
public void GetFrames_DoesNotFailForDynamicallyGeneratedAssemblies() { // Arrange var action = (Action)Expression.Lambda( Expression.Throw( Expression.New(typeof(Exception)))).Compile(); // Act try { action(); } catch (Exception exception) { var frames = StackTraceHelper.GetFrames(exception); // Assert Assert.Null(frames.First().FilePath); Assert.Equal(nameof(GetFrames_DoesNotFailForDynamicallyGeneratedAssemblies), frames.Last().Method); } }
public void GetFrames_DoesNotFailForDynamicallyGeneratedAssemblies() { // Arrange var action = (Action)Expression.Lambda( Expression.Throw( Expression.New(typeof(Exception)))).Compile(); // Act try { action(); } catch (Exception exception) { var frames = StackTraceHelper.GetFrames(exception); // Assert Assert.Null(frames.First().FilePath); Assert.Equal( $"{typeof(StackTraceTest).GetTypeInfo().FullName}.{nameof(GetFrames_DoesNotFailForDynamicallyGeneratedAssemblies)}()", frames.Last().MethodDisplayInfo.ToString()); } }
private static void WriteException(Exception ex, StringBuilder builder, ref bool wasFailingCallSiteSourceWritten) { string inlineSourceDiv = null; // First, build the stack trace var firstStackFrame = true; var stackTraceBuilder = new StringBuilder(); foreach (var frameInfo in StackTraceHelper.GetFrames(ex)) { if (!firstStackFrame) { stackTraceBuilder.Append("<br />"); } firstStackFrame = false; var thisFrameLine = BuildLineForStackFrame(frameInfo); stackTraceBuilder.AppendLine(thisFrameLine); // Try to include the source code in the error page if we can. if (!wasFailingCallSiteSourceWritten && inlineSourceDiv == null) { inlineSourceDiv = BuildCodeSnippetDiv(frameInfo); if (inlineSourceDiv != null) { wasFailingCallSiteSourceWritten = true; } } } // Finally, build the rest of the <div> builder.AppendFormat(CultureInfo.InvariantCulture, _errorExceptionFormatString, HtmlEncodeAndReplaceLineBreaks(ex.GetType().FullName), HtmlEncodeAndReplaceLineBreaks(ex.Message), inlineSourceDiv, stackTraceBuilder); }