Convert to graceful exception (#8751)
This commit is contained in:
parent
4c2b07023a
commit
3861fc1700
6 changed files with 127 additions and 114 deletions
|
@ -2,16 +2,35 @@
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace Microsoft.DotNet.Cli.Utils
|
namespace Microsoft.DotNet.Cli.Utils
|
||||||
{
|
{
|
||||||
public class GracefulException : Exception
|
public class GracefulException : Exception
|
||||||
{
|
{
|
||||||
|
public bool IsUserError { get; } = true;
|
||||||
|
public string VerboseMessage { get; } = string.Empty;
|
||||||
|
|
||||||
public GracefulException(string message) : base(message)
|
public GracefulException(string message) : base(message)
|
||||||
{
|
{
|
||||||
Data.Add(ExceptionExtensions.CLI_User_Displayed_Exception, true);
|
Data.Add(ExceptionExtensions.CLI_User_Displayed_Exception, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public GracefulException(IEnumerable<string> messages, IEnumerable<string> verboseMessages = null,
|
||||||
|
bool isUserError = true)
|
||||||
|
: base(string.Join(Environment.NewLine, messages))
|
||||||
|
{
|
||||||
|
IsUserError = isUserError;
|
||||||
|
if (verboseMessages != null)
|
||||||
|
{
|
||||||
|
VerboseMessage = string.Join(Environment.NewLine, VerboseMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
Data.Add(ExceptionExtensions.CLI_User_Displayed_Exception, true);
|
||||||
|
}
|
||||||
|
|
||||||
public GracefulException(string format, params string[] args) : this(string.Format(format, args))
|
public GracefulException(string format, params string[] args) : this(string.Format(format, args))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,19 +42,26 @@ namespace Microsoft.DotNet.Cli
|
||||||
}
|
}
|
||||||
catch (KeyNotFoundException)
|
catch (KeyNotFoundException)
|
||||||
{
|
{
|
||||||
return ReportError(CommonLocalizableStrings.RequiredCommandNotPassed);
|
Reporter.Error.WriteLine(CommonLocalizableStrings.RequiredCommandNotPassed.Red());
|
||||||
|
ParseResult.ShowHelp();
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
catch (GracefulException e)
|
catch (GracefulException e)
|
||||||
{
|
{
|
||||||
return ReportError(e.Message);
|
if (Reporter.IsVerbose)
|
||||||
}
|
{
|
||||||
}
|
Reporter.Error.WriteLine(e.VerboseMessage.Red());
|
||||||
|
}
|
||||||
|
|
||||||
private int ReportError(string errorMessage)
|
Reporter.Error.WriteLine(e.Message.Red());
|
||||||
{
|
|
||||||
Reporter.Error.WriteLine(errorMessage.Red());
|
if (e.IsUserError)
|
||||||
ParseResult.ShowHelp();
|
{
|
||||||
return 1;
|
ParseResult.ShowHelp();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -163,43 +163,41 @@ namespace Microsoft.DotNet.Tools.Install.Tool
|
||||||
}
|
}
|
||||||
catch (ToolPackageException ex)
|
catch (ToolPackageException ex)
|
||||||
{
|
{
|
||||||
if (Reporter.IsVerbose)
|
throw new GracefulException(
|
||||||
{
|
messages: new[]
|
||||||
Reporter.Verbose.WriteLine(ex.ToString().Red());
|
{
|
||||||
}
|
ex.Message,
|
||||||
|
string.Format(LocalizableStrings.ToolInstallationFailed, _packageId),
|
||||||
_errorReporter.WriteLine(ex.Message.Red());
|
},
|
||||||
_errorReporter.WriteLine(string.Format(LocalizableStrings.ToolInstallationFailed, _packageId).Red());
|
verboseMessages: new[] {ex.ToString()},
|
||||||
return 1;
|
isUserError: false);
|
||||||
}
|
}
|
||||||
catch (ToolConfigurationException ex)
|
catch (ToolConfigurationException ex)
|
||||||
{
|
{
|
||||||
if (Reporter.IsVerbose)
|
throw new GracefulException(
|
||||||
{
|
messages: new[]
|
||||||
Reporter.Verbose.WriteLine(ex.ToString().Red());
|
{
|
||||||
}
|
string.Format(
|
||||||
|
LocalizableStrings.InvalidToolConfiguration,
|
||||||
_errorReporter.WriteLine(
|
ex.Message),
|
||||||
string.Format(
|
string.Format(LocalizableStrings.ToolInstallationFailedContactAuthor, _packageId)
|
||||||
LocalizableStrings.InvalidToolConfiguration,
|
},
|
||||||
ex.Message).Red());
|
verboseMessages: new[] {ex.ToString()},
|
||||||
_errorReporter.WriteLine(string.Format(LocalizableStrings.ToolInstallationFailedContactAuthor, _packageId).Red());
|
isUserError: false);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
catch (ShellShimException ex)
|
catch (ShellShimException ex)
|
||||||
{
|
{
|
||||||
if (Reporter.IsVerbose)
|
throw new GracefulException(
|
||||||
{
|
messages: new[]
|
||||||
Reporter.Verbose.WriteLine(ex.ToString().Red());
|
{
|
||||||
}
|
string.Format(
|
||||||
|
LocalizableStrings.FailedToCreateToolShim,
|
||||||
_errorReporter.WriteLine(
|
_packageId,
|
||||||
string.Format(
|
ex.Message),
|
||||||
LocalizableStrings.FailedToCreateToolShim,
|
string.Format(LocalizableStrings.ToolInstallationFailed, _packageId)
|
||||||
_packageId,
|
},
|
||||||
ex.Message).Red());
|
verboseMessages: new[] {ex.ToString()},
|
||||||
_errorReporter.WriteLine(string.Format(LocalizableStrings.ToolInstallationFailed, _packageId).Red());
|
isUserError: false);
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,20 +74,26 @@ namespace Microsoft.DotNet.Tools.Uninstall.Tool
|
||||||
package = toolPackageStore.EnumeratePackageVersions(packageId).SingleOrDefault();
|
package = toolPackageStore.EnumeratePackageVersions(packageId).SingleOrDefault();
|
||||||
if (package == null)
|
if (package == null)
|
||||||
{
|
{
|
||||||
_errorReporter.WriteLine(
|
throw new GracefulException(
|
||||||
string.Format(
|
messages: new[]
|
||||||
LocalizableStrings.ToolNotInstalled,
|
{
|
||||||
packageId).Red());
|
string.Format(
|
||||||
return 1;
|
LocalizableStrings.ToolNotInstalled,
|
||||||
|
packageId),
|
||||||
|
},
|
||||||
|
isUserError: false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (InvalidOperationException)
|
catch (InvalidOperationException)
|
||||||
{
|
{
|
||||||
_errorReporter.WriteLine(
|
throw new GracefulException(
|
||||||
string.Format(
|
messages: new[]
|
||||||
|
{
|
||||||
|
string.Format(
|
||||||
LocalizableStrings.ToolHasMultipleVersionsInstalled,
|
LocalizableStrings.ToolHasMultipleVersionsInstalled,
|
||||||
packageId).Red());
|
packageId),
|
||||||
return 1;
|
},
|
||||||
|
isUserError: false);
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
|
@ -115,27 +121,26 @@ namespace Microsoft.DotNet.Tools.Uninstall.Tool
|
||||||
}
|
}
|
||||||
catch (ToolPackageException ex)
|
catch (ToolPackageException ex)
|
||||||
{
|
{
|
||||||
if (Reporter.IsVerbose)
|
throw new GracefulException(
|
||||||
{
|
messages: new[]
|
||||||
Reporter.Verbose.WriteLine(ex.ToString().Red());
|
{
|
||||||
}
|
ex.Message
|
||||||
|
},
|
||||||
_errorReporter.WriteLine(ex.Message.Red());
|
verboseMessages: new[] { ex.ToString() },
|
||||||
return 1;
|
isUserError: false);
|
||||||
}
|
}
|
||||||
catch (Exception ex) when (ex is ToolConfigurationException || ex is ShellShimException)
|
catch (Exception ex) when (ex is ToolConfigurationException || ex is ShellShimException)
|
||||||
{
|
{
|
||||||
if (Reporter.IsVerbose)
|
throw new GracefulException(
|
||||||
{
|
messages: new[]
|
||||||
Reporter.Verbose.WriteLine(ex.ToString().Red());
|
{
|
||||||
}
|
string.Format(
|
||||||
|
|
||||||
_errorReporter.WriteLine(
|
|
||||||
string.Format(
|
|
||||||
LocalizableStrings.FailedToUninstallTool,
|
LocalizableStrings.FailedToUninstallTool,
|
||||||
packageId,
|
packageId,
|
||||||
ex.Message).Red());
|
ex.Message)
|
||||||
return 1;
|
},
|
||||||
|
verboseMessages: new[] { ex.ToString() },
|
||||||
|
isUserError: false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,14 +152,10 @@ namespace Microsoft.DotNet.Tests.Commands
|
||||||
_environmentPathInstructionMock,
|
_environmentPathInstructionMock,
|
||||||
_reporter);
|
_reporter);
|
||||||
|
|
||||||
installToolCommand.Execute().Should().Be(1);
|
Action a = () => installToolCommand.Execute();
|
||||||
|
|
||||||
_reporter
|
a.ShouldThrow<GracefulException>().And.Message
|
||||||
.Lines
|
.Should().Contain(string.Format(LocalizableStrings.ToolInstallationFailed, PackageId));
|
||||||
.Should()
|
|
||||||
.Equal(
|
|
||||||
"Simulated error".Red(),
|
|
||||||
string.Format(LocalizableStrings.ToolInstallationFailed, PackageId).Red());
|
|
||||||
|
|
||||||
_fileSystem.Directory.Exists(Path.Combine(PathToPlacePackages, PackageId)).Should().BeFalse();
|
_fileSystem.Directory.Exists(Path.Combine(PathToPlacePackages, PackageId)).Should().BeFalse();
|
||||||
}
|
}
|
||||||
|
@ -177,15 +173,12 @@ namespace Microsoft.DotNet.Tests.Commands
|
||||||
_environmentPathInstructionMock,
|
_environmentPathInstructionMock,
|
||||||
_reporter);
|
_reporter);
|
||||||
|
|
||||||
installToolCommand.Execute().Should().Be(1);
|
Action a = () => installToolCommand.Execute();
|
||||||
|
|
||||||
_reporter
|
a.ShouldThrow<GracefulException>().And.Message
|
||||||
.Lines[0]
|
.Should().Contain(string.Format(
|
||||||
.Should()
|
CommonLocalizableStrings.ShellShimConflict,
|
||||||
.Contain(
|
ProjectRestorerMock.FakeCommandName));
|
||||||
string.Format(
|
|
||||||
CommonLocalizableStrings.ShellShimConflict,
|
|
||||||
ProjectRestorerMock.FakeCommandName));
|
|
||||||
|
|
||||||
_fileSystem.Directory.Exists(Path.Combine(PathToPlacePackages, PackageId)).Should().BeFalse();
|
_fileSystem.Directory.Exists(Path.Combine(PathToPlacePackages, PackageId)).Should().BeFalse();
|
||||||
}
|
}
|
||||||
|
@ -205,16 +198,15 @@ namespace Microsoft.DotNet.Tests.Commands
|
||||||
_environmentPathInstructionMock,
|
_environmentPathInstructionMock,
|
||||||
_reporter);
|
_reporter);
|
||||||
|
|
||||||
installToolCommand.Execute().Should().Be(1);
|
Action a = () => installToolCommand.Execute();
|
||||||
|
|
||||||
_reporter
|
a.ShouldThrow<GracefulException>().And.Message
|
||||||
.Lines
|
.Should().Contain(
|
||||||
.Should()
|
|
||||||
.Equal(
|
|
||||||
string.Format(
|
string.Format(
|
||||||
LocalizableStrings.InvalidToolConfiguration,
|
LocalizableStrings.InvalidToolConfiguration,
|
||||||
"Simulated error").Red(),
|
"Simulated error") + Environment.NewLine +
|
||||||
string.Format(LocalizableStrings.ToolInstallationFailedContactAuthor, PackageId).Red());
|
string.Format(LocalizableStrings.ToolInstallationFailedContactAuthor, PackageId)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
@ -330,15 +322,14 @@ namespace Microsoft.DotNet.Tests.Commands
|
||||||
new EnvironmentPathInstructionMock(_reporter, PathToPlaceShim, true),
|
new EnvironmentPathInstructionMock(_reporter, PathToPlaceShim, true),
|
||||||
_reporter);
|
_reporter);
|
||||||
|
|
||||||
installToolCommand.Execute().Should().Be(1);
|
Action a = () => installToolCommand.Execute();
|
||||||
|
|
||||||
_reporter
|
a.ShouldThrow<GracefulException>().And.Message
|
||||||
.Lines
|
.Should().Contain(
|
||||||
.Should()
|
LocalizableStrings.ToolInstallationRestoreFailed +
|
||||||
.Equal(
|
Environment.NewLine + string.Format(LocalizableStrings.ToolInstallationFailed, PackageId));
|
||||||
$"Error: failed to restore package {PackageId}.", // From mock implementation, not localized
|
|
||||||
LocalizableStrings.ToolInstallationRestoreFailed.Red(),
|
_fileSystem.Directory.Exists(Path.Combine(PathToPlacePackages, PackageId)).Should().BeFalse();
|
||||||
string.Format(LocalizableStrings.ToolInstallationFailed, PackageId).Red());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
|
@ -49,15 +49,13 @@ namespace Microsoft.DotNet.Tests.Commands
|
||||||
var packageId = "does.not.exist";
|
var packageId = "does.not.exist";
|
||||||
var command = CreateUninstallCommand($"-g {packageId}");
|
var command = CreateUninstallCommand($"-g {packageId}");
|
||||||
|
|
||||||
command.Execute().Should().Be(1);
|
Action a = () => command.Execute();
|
||||||
_reporter.Lines.Count.Should().Be(1);
|
|
||||||
|
|
||||||
_reporter
|
a.ShouldThrow<GracefulException>().And.Message
|
||||||
.Lines[0]
|
.Should().Contain(
|
||||||
.Should()
|
string.Format(
|
||||||
.Be(string.Format(
|
|
||||||
LocalizableStrings.ToolNotInstalled,
|
LocalizableStrings.ToolNotInstalled,
|
||||||
packageId).Red());
|
packageId));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
@ -125,20 +123,15 @@ namespace Microsoft.DotNet.Tests.Commands
|
||||||
_fileSystem.Directory.Exists(packageDirectory.Value).Should().BeTrue();
|
_fileSystem.Directory.Exists(packageDirectory.Value).Should().BeTrue();
|
||||||
_fileSystem.File.Exists(shimPath).Should().BeTrue();
|
_fileSystem.File.Exists(shimPath).Should().BeTrue();
|
||||||
|
|
||||||
_reporter.Lines.Clear();
|
Action a = () => CreateUninstallCommand(
|
||||||
|
|
||||||
CreateUninstallCommand(
|
|
||||||
options: $"-g {PackageId}",
|
options: $"-g {PackageId}",
|
||||||
uninstallCallback: () => throw new IOException("simulated error"))
|
uninstallCallback: () => throw new IOException("simulated error"))
|
||||||
.Execute()
|
.Execute();
|
||||||
.Should()
|
|
||||||
.Be(1);
|
|
||||||
|
|
||||||
_reporter
|
a.ShouldThrow<GracefulException>()
|
||||||
.Lines
|
.And.Message
|
||||||
.Single()
|
.Should().Contain(
|
||||||
.Should()
|
string.Format(
|
||||||
.Contain(string.Format(
|
|
||||||
CommonLocalizableStrings.FailedToUninstallToolPackage,
|
CommonLocalizableStrings.FailedToUninstallToolPackage,
|
||||||
PackageId,
|
PackageId,
|
||||||
"simulated error"));
|
"simulated error"));
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue