Skip to content

Commit af64e33

Browse files
committed
C#: Gracefully handle non-zero exitcodes for dotnet --info.
1 parent c43b03b commit af64e33

File tree

4 files changed

+50
-7
lines changed

4 files changed

+50
-7
lines changed

csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,18 @@ private DotNet(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkin
3838

3939
private void Info()
4040
{
41-
var res = dotnetCliInvoker.RunCommand("--info", silent: false);
42-
if (!res)
41+
var exitCode = dotnetCliInvoker.RunCommandExitCode("--info", silent: false);
42+
switch (exitCode)
4343
{
44-
throw new Exception($"{dotnetCliInvoker.Exec} --info failed.");
44+
case 0:
45+
break;
46+
case 143:
47+
logger.LogWarning("Running 'dotnet --info' failed with exit code 143.");
48+
break;
49+
default:
50+
throw new Exception($"{dotnetCliInvoker.Exec} --info failed with exit code {exitCode}.");
4551
}
52+
4653
}
4754

4855
private string GetRestoreArgs(RestoreSettings restoreSettings)

csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNetCliInvoker.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,21 @@ private ProcessStartInfo MakeDotnetStartInfo(string args, string? workingDirecto
5757
return startInfo;
5858
}
5959

60-
private bool RunCommandAux(string args, string? workingDirectory, out IList<string> output, bool silent)
60+
private int RunCommandExitCodeAux(string args, string? workingDirectory, out IList<string> output, out string dirLog, bool silent)
6161
{
62-
var dirLog = string.IsNullOrWhiteSpace(workingDirectory) ? "" : $" in {workingDirectory}";
62+
dirLog = string.IsNullOrWhiteSpace(workingDirectory) ? "" : $" in {workingDirectory}";
6363
var pi = MakeDotnetStartInfo(args, workingDirectory);
6464
var threadId = Environment.CurrentManagedThreadId;
6565
void onOut(string s) => logger.Log(silent ? Severity.Debug : Severity.Info, s, threadId);
6666
void onError(string s) => logger.LogError(s, threadId);
6767
logger.LogInfo($"Running '{Exec} {args}'{dirLog}");
6868
var exitCode = pi.ReadOutput(out output, onOut, onError);
69+
return exitCode;
70+
}
71+
72+
private bool RunCommandAux(string args, string? workingDirectory, out IList<string> output, bool silent)
73+
{
74+
var exitCode = RunCommandExitCodeAux(args, workingDirectory, out output, out var dirLog, silent);
6975
if (exitCode != 0)
7076
{
7177
logger.LogError($"Command '{Exec} {args}'{dirLog} failed with exit code {exitCode}");
@@ -77,6 +83,9 @@ private bool RunCommandAux(string args, string? workingDirectory, out IList<stri
7783
public bool RunCommand(string args, bool silent = true) =>
7884
RunCommandAux(args, null, out _, silent);
7985

86+
public int RunCommandExitCode(string args, bool silent = true) =>
87+
RunCommandExitCodeAux(args, null, out _, out _, silent);
88+
8089
public bool RunCommand(string args, out IList<string> output, bool silent = true) =>
8190
RunCommandAux(args, null, out output, silent);
8291

csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/IDotNetCliInvoker.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ internal interface IDotNetCliInvoker
3030
/// </summary>
3131
bool RunCommand(string args, bool silent = true);
3232

33+
/// <summary>
34+
/// Execute `dotnet <paramref name="args"/>` and return the exit code.
35+
/// If `silent` is true the output of the command is logged as `debug` otherwise as `info`.
36+
/// </summary>
37+
int RunCommandExitCode(string args, bool silent = true);
38+
3339
/// <summary>
3440
/// Execute `dotnet <paramref name="args"/>` and return true if the command succeeded, otherwise false.
3541
/// The output of the command is returned in `output`.

csharp/extractor/Semmle.Extraction.Tests/DotNet.cs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ internal class DotNetCliInvokerStub : IDotNetCliInvoker
1212
private string lastArgs = "";
1313
public string WorkingDirectory { get; private set; } = "";
1414
public bool Success { get; set; } = true;
15+
public int ExitCode { get; set; } = 0;
1516

1617
public DotNetCliInvokerStub(IList<string> output)
1718
{
@@ -26,6 +27,12 @@ public bool RunCommand(string args, bool silent)
2627
return Success;
2728
}
2829

30+
public int RunCommandExitCode(string args, bool silent)
31+
{
32+
lastArgs = args;
33+
return ExitCode;
34+
}
35+
2936
public bool RunCommand(string args, out IList<string> output, bool silent)
3037
{
3138
lastArgs = args;
@@ -83,7 +90,7 @@ public void TestDotnetInfo()
8390
public void TestDotnetInfoFailure()
8491
{
8592
// Setup
86-
var dotnetCliInvoker = new DotNetCliInvokerStub(new List<string>()) { Success = false };
93+
var dotnetCliInvoker = new DotNetCliInvokerStub(new List<string>()) { ExitCode = 1 };
8794

8895
// Execute
8996
try
@@ -94,12 +101,26 @@ public void TestDotnetInfoFailure()
94101
// Verify
95102
catch (Exception e)
96103
{
97-
Assert.Equal("dotnet --info failed.", e.Message);
104+
Assert.Equal("dotnet --info failed with exit code 1.", e.Message);
98105
return;
99106
}
100107
Assert.Fail("Expected exception");
101108
}
102109

110+
[Fact]
111+
public void TestDotnetInfoExitCode143()
112+
{
113+
// Setup
114+
var dotnetCliInvoker = new DotNetCliInvokerStub(new List<string>()) { ExitCode = 143 };
115+
116+
// Execute
117+
_ = MakeDotnet(dotnetCliInvoker);
118+
119+
// Verify
120+
var lastArgs = dotnetCliInvoker.GetLastArgs();
121+
Assert.Equal("--info", lastArgs);
122+
}
123+
103124
[Fact]
104125
public void TestDotnetRestoreProjectToDirectory1()
105126
{

0 commit comments

Comments
 (0)