Skip to content

Commit

Permalink
Collect crash exception (#3318)
Browse files Browse the repository at this point in the history
  • Loading branch information
William Li authored Jun 12, 2019
1 parent 9d81590 commit fce5096
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 0 deletions.
67 changes: 67 additions & 0 deletions src/Tasks/Common/TaskBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

using System;
using Microsoft.Build.Utilities;
using Microsoft.Build.Framework;
using System.Collections.Generic;
using System.Globalization;

namespace Microsoft.NET.Build.Tasks
{
Expand Down Expand Up @@ -38,10 +41,74 @@ public override bool Execute()
{
Log.LogError(e.Message);
}
catch (Exception e)
{
LogErrorTelemetry("taskBaseCatchException", e);
throw;
}

return !Log.HasLoggedErrors;
}

private void LogErrorTelemetry(string eventName, Exception e)
{
(BuildEngine as IBuildEngine5)?.LogTelemetry(eventName, new Dictionary<string, string> {
{"exceptionType", e.GetType().ToString() },
{"detail", ExceptionToStringWithoutMessage(e) }});
}

private static string ExceptionToStringWithoutMessage(Exception e)
{
const string AggregateException_ToString = "{0}{1}---> (Inner Exception #{2}) {3}{4}{5}";
if (e is AggregateException aggregate)
{
string text = NonAggregateExceptionToStringWithoutMessage(aggregate);

for (int i = 0; i < aggregate.InnerExceptions.Count; i++)
{
text = string.Format(CultureInfo.InvariantCulture,
AggregateException_ToString,
text,
Environment.NewLine,
i,
ExceptionToStringWithoutMessage(aggregate.InnerExceptions[i]),
"<---",
Environment.NewLine);
}

return text;
}
else
{
return NonAggregateExceptionToStringWithoutMessage(e);
}
}

private static string NonAggregateExceptionToStringWithoutMessage(Exception e)
{
string s;
const string Exception_EndOfInnerExceptionStack = "--- End of inner exception stack trace ---";


s = e.GetType().ToString();

if (e.InnerException != null)
{
s = s + " ---> " + ExceptionToStringWithoutMessage(e.InnerException) + Environment.NewLine +
" " + Exception_EndOfInnerExceptionStack;

}

var stackTrace = e.StackTrace;

if (stackTrace != null)
{
s += Environment.NewLine + stackTrace;
}

return s;
}

protected abstract void ExecuteCore();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using FluentAssertions;
using Microsoft.NET.TestFramework;
using Microsoft.NET.TestFramework.Assertions;
using Microsoft.NET.TestFramework.Commands;
using System;
using System.IO;
using Xunit.Abstractions;
using System.Reflection;

namespace Microsoft.NET.Build.Tests
{
public class GivenThatWeWantToCollectExceptionTelemetry : SdkTest
{
public GivenThatWeWantToCollectExceptionTelemetry(ITestOutputHelper log) : base(log)
{
}

[CoreMSBuildAndWindowsOnlyFact]
public void It_collects_Exception()
{
Type loggerType = typeof(LogTelemetryToStdOutForTest);
string telemetryTestLogger = $"/Logger:{loggerType.FullName},{loggerType.GetTypeInfo().Assembly.Location}";

var testAsset = _testAssetsManager.CopyTestAsset("HelloWorld").WithSource().Restore(Log);

var mSBuildCommand = new MSBuildCommand(Log, "GenerateToolsSettingsFileFromBuildProperty", Path.Combine(testAsset.TestRoot));

string invalidPath = @"\\.\COM56";
string causeTaskToFail = $"/p:_ToolsSettingsFilePath={invalidPath}";

mSBuildCommand
.Execute(telemetryTestLogger, causeTaskToFail)
.StdOut.Should()
.Contain("\"EventName\":\"taskBaseCatchException\",\"Properties\":{\"exceptionType\":\"System.IO.FileNotFoundException\"")
.And.Contain("detail");
}
}
}

0 comments on commit fce5096

Please sign in to comment.