Skip to content
This repository was archived by the owner on Apr 20, 2023. It is now read-only.

Commit 3861fc1

Browse files
author
William Lee
authored
Convert to graceful exception (#8751)
1 parent 4c2b070 commit 3861fc1

File tree

6 files changed

+127
-114
lines changed

6 files changed

+127
-114
lines changed

src/Microsoft.DotNet.Cli.Utils/GracefulException.cs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,35 @@
22
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
33

44
using System;
5+
using System.Collections.Generic;
6+
using System.Linq;
57

68
namespace Microsoft.DotNet.Cli.Utils
79
{
810
public class GracefulException : Exception
911
{
12+
public bool IsUserError { get; } = true;
13+
public string VerboseMessage { get; } = string.Empty;
14+
1015
public GracefulException(string message) : base(message)
1116
{
1217
Data.Add(ExceptionExtensions.CLI_User_Displayed_Exception, true);
1318
}
1419

20+
21+
public GracefulException(IEnumerable<string> messages, IEnumerable<string> verboseMessages = null,
22+
bool isUserError = true)
23+
: base(string.Join(Environment.NewLine, messages))
24+
{
25+
IsUserError = isUserError;
26+
if (verboseMessages != null)
27+
{
28+
VerboseMessage = string.Join(Environment.NewLine, VerboseMessage);
29+
}
30+
31+
Data.Add(ExceptionExtensions.CLI_User_Displayed_Exception, true);
32+
}
33+
1534
public GracefulException(string format, params string[] args) : this(string.Format(format, args))
1635
{
1736
}

src/dotnet/DotNetTopLevelCommandBase.cs

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,19 +42,26 @@ public int RunCommand(string[] args)
4242
}
4343
catch (KeyNotFoundException)
4444
{
45-
return ReportError(CommonLocalizableStrings.RequiredCommandNotPassed);
45+
Reporter.Error.WriteLine(CommonLocalizableStrings.RequiredCommandNotPassed.Red());
46+
ParseResult.ShowHelp();
47+
return 1;
4648
}
4749
catch (GracefulException e)
4850
{
49-
return ReportError(e.Message);
50-
}
51-
}
51+
if (Reporter.IsVerbose)
52+
{
53+
Reporter.Error.WriteLine(e.VerboseMessage.Red());
54+
}
55+
56+
Reporter.Error.WriteLine(e.Message.Red());
57+
58+
if (e.IsUserError)
59+
{
60+
ParseResult.ShowHelp();
61+
}
5262

53-
private int ReportError(string errorMessage)
54-
{
55-
Reporter.Error.WriteLine(errorMessage.Red());
56-
ParseResult.ShowHelp();
57-
return 1;
63+
return 1;
64+
}
5865
}
5966
}
60-
}
67+
}

src/dotnet/commands/dotnet-install/dotnet-install-tool/InstallToolCommand.cs

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -163,43 +163,41 @@ public override int Execute()
163163
}
164164
catch (ToolPackageException ex)
165165
{
166-
if (Reporter.IsVerbose)
167-
{
168-
Reporter.Verbose.WriteLine(ex.ToString().Red());
169-
}
170-
171-
_errorReporter.WriteLine(ex.Message.Red());
172-
_errorReporter.WriteLine(string.Format(LocalizableStrings.ToolInstallationFailed, _packageId).Red());
173-
return 1;
166+
throw new GracefulException(
167+
messages: new[]
168+
{
169+
ex.Message,
170+
string.Format(LocalizableStrings.ToolInstallationFailed, _packageId),
171+
},
172+
verboseMessages: new[] {ex.ToString()},
173+
isUserError: false);
174174
}
175175
catch (ToolConfigurationException ex)
176176
{
177-
if (Reporter.IsVerbose)
178-
{
179-
Reporter.Verbose.WriteLine(ex.ToString().Red());
180-
}
181-
182-
_errorReporter.WriteLine(
183-
string.Format(
184-
LocalizableStrings.InvalidToolConfiguration,
185-
ex.Message).Red());
186-
_errorReporter.WriteLine(string.Format(LocalizableStrings.ToolInstallationFailedContactAuthor, _packageId).Red());
187-
return 1;
177+
throw new GracefulException(
178+
messages: new[]
179+
{
180+
string.Format(
181+
LocalizableStrings.InvalidToolConfiguration,
182+
ex.Message),
183+
string.Format(LocalizableStrings.ToolInstallationFailedContactAuthor, _packageId)
184+
},
185+
verboseMessages: new[] {ex.ToString()},
186+
isUserError: false);
188187
}
189188
catch (ShellShimException ex)
190189
{
191-
if (Reporter.IsVerbose)
192-
{
193-
Reporter.Verbose.WriteLine(ex.ToString().Red());
194-
}
195-
196-
_errorReporter.WriteLine(
197-
string.Format(
198-
LocalizableStrings.FailedToCreateToolShim,
199-
_packageId,
200-
ex.Message).Red());
201-
_errorReporter.WriteLine(string.Format(LocalizableStrings.ToolInstallationFailed, _packageId).Red());
202-
return 1;
190+
throw new GracefulException(
191+
messages: new[]
192+
{
193+
string.Format(
194+
LocalizableStrings.FailedToCreateToolShim,
195+
_packageId,
196+
ex.Message),
197+
string.Format(LocalizableStrings.ToolInstallationFailed, _packageId)
198+
},
199+
verboseMessages: new[] {ex.ToString()},
200+
isUserError: false);
203201
}
204202
}
205203
}

src/dotnet/commands/dotnet-uninstall/tool/UninstallToolCommand.cs

Lines changed: 30 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -74,20 +74,26 @@ public override int Execute()
7474
package = toolPackageStore.EnumeratePackageVersions(packageId).SingleOrDefault();
7575
if (package == null)
7676
{
77-
_errorReporter.WriteLine(
78-
string.Format(
79-
LocalizableStrings.ToolNotInstalled,
80-
packageId).Red());
81-
return 1;
77+
throw new GracefulException(
78+
messages: new[]
79+
{
80+
string.Format(
81+
LocalizableStrings.ToolNotInstalled,
82+
packageId),
83+
},
84+
isUserError: false);
8285
}
8386
}
8487
catch (InvalidOperationException)
8588
{
86-
_errorReporter.WriteLine(
87-
string.Format(
89+
throw new GracefulException(
90+
messages: new[]
91+
{
92+
string.Format(
8893
LocalizableStrings.ToolHasMultipleVersionsInstalled,
89-
packageId).Red());
90-
return 1;
94+
packageId),
95+
},
96+
isUserError: false);
9197
}
9298

9399
try
@@ -115,27 +121,26 @@ public override int Execute()
115121
}
116122
catch (ToolPackageException ex)
117123
{
118-
if (Reporter.IsVerbose)
119-
{
120-
Reporter.Verbose.WriteLine(ex.ToString().Red());
121-
}
122-
123-
_errorReporter.WriteLine(ex.Message.Red());
124-
return 1;
124+
throw new GracefulException(
125+
messages: new[]
126+
{
127+
ex.Message
128+
},
129+
verboseMessages: new[] { ex.ToString() },
130+
isUserError: false);
125131
}
126132
catch (Exception ex) when (ex is ToolConfigurationException || ex is ShellShimException)
127133
{
128-
if (Reporter.IsVerbose)
129-
{
130-
Reporter.Verbose.WriteLine(ex.ToString().Red());
131-
}
132-
133-
_errorReporter.WriteLine(
134-
string.Format(
134+
throw new GracefulException(
135+
messages: new[]
136+
{
137+
string.Format(
135138
LocalizableStrings.FailedToUninstallTool,
136139
packageId,
137-
ex.Message).Red());
138-
return 1;
140+
ex.Message)
141+
},
142+
verboseMessages: new[] { ex.ToString() },
143+
isUserError: false);
139144
}
140145
}
141146
}

test/dotnet.Tests/CommandTests/InstallToolCommandTests.cs

Lines changed: 21 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -152,14 +152,10 @@ public void GivenFailedPackageInstallWhenRunWithPackageIdItShouldFail()
152152
_environmentPathInstructionMock,
153153
_reporter);
154154

155-
installToolCommand.Execute().Should().Be(1);
155+
Action a = () => installToolCommand.Execute();
156156

157-
_reporter
158-
.Lines
159-
.Should()
160-
.Equal(
161-
"Simulated error".Red(),
162-
string.Format(LocalizableStrings.ToolInstallationFailed, PackageId).Red());
157+
a.ShouldThrow<GracefulException>().And.Message
158+
.Should().Contain(string.Format(LocalizableStrings.ToolInstallationFailed, PackageId));
163159

164160
_fileSystem.Directory.Exists(Path.Combine(PathToPlacePackages, PackageId)).Should().BeFalse();
165161
}
@@ -177,15 +173,12 @@ public void GivenCreateShimItShouldHaveNoBrokenFolderOnDisk()
177173
_environmentPathInstructionMock,
178174
_reporter);
179175

180-
installToolCommand.Execute().Should().Be(1);
176+
Action a = () => installToolCommand.Execute();
181177

182-
_reporter
183-
.Lines[0]
184-
.Should()
185-
.Contain(
186-
string.Format(
187-
CommonLocalizableStrings.ShellShimConflict,
188-
ProjectRestorerMock.FakeCommandName));
178+
a.ShouldThrow<GracefulException>().And.Message
179+
.Should().Contain(string.Format(
180+
CommonLocalizableStrings.ShellShimConflict,
181+
ProjectRestorerMock.FakeCommandName));
189182

190183
_fileSystem.Directory.Exists(Path.Combine(PathToPlacePackages, PackageId)).Should().BeFalse();
191184
}
@@ -205,16 +198,15 @@ public void GivenInCorrectToolConfigurationWhenRunWithPackageIdItShouldFail()
205198
_environmentPathInstructionMock,
206199
_reporter);
207200

208-
installToolCommand.Execute().Should().Be(1);
201+
Action a = () => installToolCommand.Execute();
209202

210-
_reporter
211-
.Lines
212-
.Should()
213-
.Equal(
203+
a.ShouldThrow<GracefulException>().And.Message
204+
.Should().Contain(
214205
string.Format(
215206
LocalizableStrings.InvalidToolConfiguration,
216-
"Simulated error").Red(),
217-
string.Format(LocalizableStrings.ToolInstallationFailedContactAuthor, PackageId).Red());
207+
"Simulated error") + Environment.NewLine +
208+
string.Format(LocalizableStrings.ToolInstallationFailedContactAuthor, PackageId)
209+
);
218210
}
219211

220212
[Fact]
@@ -330,15 +322,14 @@ public void WhenRunWithoutAMatchingRangeItShouldFail()
330322
new EnvironmentPathInstructionMock(_reporter, PathToPlaceShim, true),
331323
_reporter);
332324

333-
installToolCommand.Execute().Should().Be(1);
325+
Action a = () => installToolCommand.Execute();
334326

335-
_reporter
336-
.Lines
337-
.Should()
338-
.Equal(
339-
$"Error: failed to restore package {PackageId}.", // From mock implementation, not localized
340-
LocalizableStrings.ToolInstallationRestoreFailed.Red(),
341-
string.Format(LocalizableStrings.ToolInstallationFailed, PackageId).Red());
327+
a.ShouldThrow<GracefulException>().And.Message
328+
.Should().Contain(
329+
LocalizableStrings.ToolInstallationRestoreFailed +
330+
Environment.NewLine + string.Format(LocalizableStrings.ToolInstallationFailed, PackageId));
331+
332+
_fileSystem.Directory.Exists(Path.Combine(PathToPlacePackages, PackageId)).Should().BeFalse();
342333
}
343334

344335
[Fact]

test/dotnet.Tests/CommandTests/UninstallToolCommandTests.cs

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,13 @@ public void GivenANonExistentPackageItErrors()
4949
var packageId = "does.not.exist";
5050
var command = CreateUninstallCommand($"-g {packageId}");
5151

52-
command.Execute().Should().Be(1);
53-
_reporter.Lines.Count.Should().Be(1);
52+
Action a = () => command.Execute();
5453

55-
_reporter
56-
.Lines[0]
57-
.Should()
58-
.Be(string.Format(
54+
a.ShouldThrow<GracefulException>().And.Message
55+
.Should().Contain(
56+
string.Format(
5957
LocalizableStrings.ToolNotInstalled,
60-
packageId).Red());
58+
packageId));
6159
}
6260

6361
[Fact]
@@ -125,20 +123,15 @@ public void GivenAFailureToUninstallItLeavesItInstalled()
125123
_fileSystem.Directory.Exists(packageDirectory.Value).Should().BeTrue();
126124
_fileSystem.File.Exists(shimPath).Should().BeTrue();
127125

128-
_reporter.Lines.Clear();
129-
130-
CreateUninstallCommand(
126+
Action a = () => CreateUninstallCommand(
131127
options: $"-g {PackageId}",
132128
uninstallCallback: () => throw new IOException("simulated error"))
133-
.Execute()
134-
.Should()
135-
.Be(1);
129+
.Execute();
136130

137-
_reporter
138-
.Lines
139-
.Single()
140-
.Should()
141-
.Contain(string.Format(
131+
a.ShouldThrow<GracefulException>()
132+
.And.Message
133+
.Should().Contain(
134+
string.Format(
142135
CommonLocalizableStrings.FailedToUninstallToolPackage,
143136
PackageId,
144137
"simulated error"));

0 commit comments

Comments
 (0)