Skip to content

Commit 12f9ddc

Browse files
authored
Use Get-Error instead of custom error formatting logic (#395)
* Relax ErrorRecordFormatter unit test expectationsEnsure the required data is there, but don't insist on formatting specifics. * Replace custom error formatting with Get-Error
1 parent 317ecb1 commit 12f9ddc

File tree

2 files changed

+21
-87
lines changed

2 files changed

+21
-87
lines changed

src/PowerShell/ErrorRecordFormatter.cs

Lines changed: 9 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ namespace Microsoft.Azure.Functions.PowerShellWorker.PowerShell
1313
internal class ErrorRecordFormatter
1414
{
1515
private const string TruncationPostfix = "...";
16-
private const string Indent = " ";
1716

1817
private readonly PowerShell _pwsh = PowerShell.Create();
1918

@@ -26,89 +25,23 @@ internal class ErrorRecordFormatter
2625
/// </summary>
2726
public string Format(ErrorRecord errorRecord, int maxSize = 1 * 1024 * 1024)
2827
{
29-
_pwsh.AddScript("$ErrorView = 'NormalView'").InvokeAndClearCommands();
30-
var errorDetails = _pwsh.AddCommand("Microsoft.PowerShell.Utility\\Out-String")
28+
var errorDetails = _pwsh.AddCommand("Microsoft.PowerShell.Utility\\Get-Error")
3129
.AddParameter("InputObject", errorRecord)
30+
.AddCommand("Microsoft.PowerShell.Utility\\Out-String")
3231
.InvokeAndClearCommands<string>();
3332

34-
var result = new StringBuilder(
35-
capacity: Math.Min(1024, maxSize),
36-
maxCapacity: maxSize);
33+
var result = new StringBuilder(capacity: Math.Min(1024, maxSize));
3734

38-
try
39-
{
40-
result.Append(errorDetails.Single());
41-
result.AppendLine("Script stack trace:");
42-
AppendStackTrace(result, errorRecord.ScriptStackTrace, Indent);
43-
result.AppendLine();
44-
45-
if (errorRecord.Exception != null)
46-
{
47-
AppendExceptionWithInners(result, errorRecord.Exception);
48-
}
49-
50-
return result.ToString();
51-
}
52-
catch (ArgumentOutOfRangeException) // exceeding StringBuilder max capacity
53-
{
54-
return Truncate(result, maxSize);
55-
}
56-
}
57-
58-
private static void AppendExceptionWithInners(StringBuilder result, Exception exception)
59-
{
60-
AppendExceptionInfo(result, exception);
61-
62-
if (exception is AggregateException aggregateException)
63-
{
64-
foreach (var innerException in aggregateException.Flatten().InnerExceptions)
65-
{
66-
AppendInnerExceptionIfNotNull(result, innerException);
67-
}
68-
}
69-
else
70-
{
71-
AppendInnerExceptionIfNotNull(result, exception.InnerException);
72-
}
73-
}
74-
75-
private static void AppendInnerExceptionIfNotNull(StringBuilder result, Exception innerException)
76-
{
77-
if (innerException != null)
78-
{
79-
result.Append("Inner exception: ");
80-
AppendExceptionWithInners(result, innerException);
81-
}
82-
}
83-
84-
private static void AppendExceptionInfo(StringBuilder stringBuilder, Exception exception)
85-
{
86-
stringBuilder.Append(exception.GetType().FullName);
87-
stringBuilder.Append(": ");
88-
stringBuilder.AppendLine(exception.Message);
89-
90-
AppendStackTrace(stringBuilder, exception.StackTrace, string.Empty);
91-
stringBuilder.AppendLine();
92-
}
93-
94-
private static void AppendStackTrace(StringBuilder stringBuilder, string stackTrace, string indent)
95-
{
96-
if (stackTrace != null)
97-
{
98-
stringBuilder.Append(indent);
99-
stringBuilder.AppendLine(stackTrace.Replace(Environment.NewLine, Environment.NewLine + indent));
100-
}
101-
}
102-
103-
private static string Truncate(StringBuilder result, int maxSize)
104-
{
105-
var charactersToRemove = result.Length + TruncationPostfix.Length - maxSize;
106-
if (charactersToRemove > 0)
35+
result.AppendLine(errorRecord.Exception.Message);
36+
result.Append(errorDetails.Single());
37+
if (result.Length > maxSize)
10738
{
39+
var charactersToRemove = result.Length + TruncationPostfix.Length - maxSize;
10840
result.Remove(result.Length - charactersToRemove, charactersToRemove);
41+
result.Append(TruncationPostfix);
10942
}
11043

111-
return result + TruncationPostfix;
44+
return result.ToString();
11245
}
11346
}
11447
}

test/Unit/PowerShell/ErrorRecordFormatterTests.cs

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public void FormattedStringContainsBasicErrorRecordData()
3030
var resultLines = result.Split(Environment.NewLine);
3131
Assert.Contains(resultLines, line => Regex.IsMatch(line, @"\bCategoryInfo\b[:\s]*?\bInvalidOperation\b"));
3232
Assert.Contains(resultLines, line => Regex.IsMatch(line, @"\bFullyQualifiedErrorId\b[:\s]*?\berror id\b"));
33-
Assert.Contains(resultLines, line => line == "System.Management.Automation.RuntimeException: My exception");
33+
Assert.Contains(resultLines, line => Regex.IsMatch(line, @"\bSystem.Management.Automation.RuntimeException\b"));
3434
}
3535

3636
[Fact]
@@ -44,9 +44,9 @@ public void FormattedStringContainsInnerExceptions()
4444
var result = s_errorRecordFormatter.Format(errorRecord);
4545

4646
var resultLines = result.Split(Environment.NewLine);
47-
Assert.Contains(resultLines, line => line == "Inner exception: System.Exception: My exception 1");
48-
Assert.Contains(resultLines, line => line == "Inner exception: System.Exception: My exception 2");
49-
Assert.Equal(2, resultLines.Count(line => line.Contains("Inner exception:")));
47+
Assert.Contains(resultLines, line => line.Contains(exception1.Message));
48+
Assert.Contains(resultLines, line => line.Contains(exception2.Message));
49+
Assert.Equal(2, resultLines.Count(line => Regex.IsMatch(line, @"\binner", RegexOptions.IgnoreCase)));
5050
}
5151

5252
[Fact]
@@ -64,13 +64,13 @@ public void FormattedStringContainsAggregateExceptionMembers()
6464
var result = s_errorRecordFormatter.Format(errorRecord);
6565

6666
var resultLines = result.Split(Environment.NewLine);
67-
Assert.Contains(resultLines, line => line == "Inner exception: System.Exception: My exception 1");
68-
Assert.Contains(resultLines, line => line == "Inner exception: System.Exception: My exception 2");
69-
Assert.Contains(resultLines, line => line.StartsWith("Inner exception: System.AggregateException: My exception 3"));
70-
Assert.Contains(resultLines, line => line == "Inner exception: System.Exception: My exception 4");
71-
Assert.Contains(resultLines, line => line == "Inner exception: System.Exception: My exception 5");
72-
Assert.Contains(resultLines, line => line.StartsWith("Inner exception: System.AggregateException: My exception 6"));
73-
Assert.Contains(resultLines, line => line == "System.Exception: My exception 7");
67+
Assert.Contains(resultLines, line => line.Contains(exception1.Message));
68+
Assert.Contains(resultLines, line => line.Contains(exception2.Message));
69+
Assert.Contains(resultLines, line => line.Contains(exception3.Message));
70+
Assert.Contains(resultLines, line => line.Contains(exception4.Message));
71+
Assert.Contains(resultLines, line => line.Contains(exception5.Message));
72+
Assert.Contains(resultLines, line => line.Contains(exception6.Message));
73+
Assert.Contains(resultLines, line => line.Contains(exception7.Message));
7474
}
7575

7676
[Fact]
@@ -89,6 +89,7 @@ public void FormattedStringIsTruncatedIfTooLong()
8989
Assert.InRange(truncatedResult.Length, ExpectedPostfix.Length + 1, maxSize);
9090
Assert.EndsWith(ExpectedPostfix, truncatedResult);
9191
Assert.StartsWith(fullResult.Substring(0, truncatedResult.Length - ExpectedPostfix.Length), truncatedResult);
92+
Assert.Equal(maxSize, truncatedResult.Length);
9293
}
9394
}
9495
}

0 commit comments

Comments
 (0)