diff --git a/src/AWS.Deploy.CLI/AWSUtilities.cs b/src/AWS.Deploy.CLI/AWSUtilities.cs
index 4e7cc7d04..d0c6a47b8 100644
--- a/src/AWS.Deploy.CLI/AWSUtilities.cs
+++ b/src/AWS.Deploy.CLI/AWSUtilities.cs
@@ -80,7 +80,7 @@ await CanLoadCredentials(lastUsedCredentials))
var sharedCredentials = new SharedCredentialsFile();
if (sharedCredentials.ListProfileNames().Count == 0)
{
- throw new NoAWSCredentialsFoundException("Unable to resolve AWS credentials to access AWS.");
+ throw new NoAWSCredentialsFoundException(DeployToolErrorCode.UnableToResolveAWSCredentials, "Unable to resolve AWS credentials to access AWS.");
}
var selectedProfileName = _consoleUtilities.AskUserToChoose(sharedCredentials.ListProfileNames(), "Select AWS Credentials Profile", null);
@@ -91,7 +91,7 @@ await CanLoadCredentials(lastUsedCredentials))
return selectedProfileCredentials;
}
- throw new NoAWSCredentialsFoundException($"Unable to create AWS credentials for profile {selectedProfileName}.");
+ throw new NoAWSCredentialsFoundException(DeployToolErrorCode.UnableToCreateAWSCredentials, $"Unable to create AWS credentials for profile {selectedProfileName}.");
}
var credentials = await Resolve();
diff --git a/src/AWS.Deploy.CLI/CommandReturnCodes.cs b/src/AWS.Deploy.CLI/CommandReturnCodes.cs
index 3102ead26..78fe2d275 100644
--- a/src/AWS.Deploy.CLI/CommandReturnCodes.cs
+++ b/src/AWS.Deploy.CLI/CommandReturnCodes.cs
@@ -16,8 +16,8 @@ public class CommandReturnCodes
/// exception was thrown. This usually means there is an intermittent io problem
/// or bug in the code base.
///
- /// Unexpected exception are any exception not marked by
- ///
+ /// Unexpected exceptions are any exception that do not inherit from
+ ///
///
public const int UNHANDLED_EXCEPTION = -1;
///
@@ -25,8 +25,8 @@ public class CommandReturnCodes
/// configuration or system configuration problem. For example, a required
/// dependency like Docker is not installed.
///
- /// Expected problems are usually indicated by throwing an exception that is
- /// decorated with
+ /// Expected problems are usually indicated by throwing an exception that
+ /// inherits from
///
public const int USER_ERROR = 1;
///
diff --git a/src/AWS.Deploy.CLI/Commands/DeleteDeploymentCommand.cs b/src/AWS.Deploy.CLI/Commands/DeleteDeploymentCommand.cs
index baf5af13a..29bd42ad1 100644
--- a/src/AWS.Deploy.CLI/Commands/DeleteDeploymentCommand.cs
+++ b/src/AWS.Deploy.CLI/Commands/DeleteDeploymentCommand.cs
@@ -126,10 +126,10 @@ private async Task WaitForStackDelete(string stackName)
if (stack.StackStatus.IsFailed())
{
- throw new FailedToDeleteException($"The stack {stackName} is in a failed state. You may need to delete it from the AWS Console.");
+ throw new FailedToDeleteException(DeployToolErrorCode.FailedToDeleteStack, $"The stack {stackName} is in a failed state. You may need to delete it from the AWS Console.");
}
- throw new FailedToDeleteException($"Failed to delete {stackName} stack: {stack.StackStatus}");
+ throw new FailedToDeleteException(DeployToolErrorCode.FailedToDeleteStack, $"Failed to delete {stackName} stack: {stack.StackStatus}");
}
private async Task StabilizeStack(string stackName)
diff --git a/src/AWS.Deploy.CLI/Commands/DeployCommand.cs b/src/AWS.Deploy.CLI/Commands/DeployCommand.cs
index 8ea3fafe7..5f8be7ab2 100644
--- a/src/AWS.Deploy.CLI/Commands/DeployCommand.cs
+++ b/src/AWS.Deploy.CLI/Commands/DeployCommand.cs
@@ -179,7 +179,7 @@ private void DisplayOutputResources(List displayedResourc
if (!compatibleApplications.Any(app => app.StackName.Equals(deployedApplication.StackName, StringComparison.Ordinal)))
{
var errorMessage = $"{deployedApplication.StackName} already exists as a Cloudformation stack but a compatible recommendation to perform a redeployment was not found";
- throw new FailedToFindCompatibleRecipeException(errorMessage);
+ throw new FailedToFindCompatibleRecipeException(DeployToolErrorCode.CompatibleRecommendationForRedeploymentNotFound, errorMessage);
}
// preset settings for deployment based on last deployment.
@@ -219,7 +219,7 @@ public async Task EvaluateSystemCapabilities(Recommendation selectedRecommendati
}
if (systemCapabilities.Any())
- throw new MissingSystemCapabilityException(missingCapabilitiesMessage);
+ throw new MissingSystemCapabilityException(DeployToolErrorCode.MissingSystemCapabilities, missingCapabilitiesMessage);
}
///
@@ -253,7 +253,7 @@ private async Task> GenerateDeploymentRecommendations(Orche
if (!recommendations.Any())
{
var errorMessage = $"Could not find any deployment recipe located inside '{deploymentProjectPath}' that can be used for deployment of the target application";
- throw new FailedToGenerateAnyRecommendations(errorMessage);
+ throw new FailedToGenerateAnyRecommendations(DeployToolErrorCode.NoDeploymentRecipesFound, errorMessage);
}
}
else
@@ -262,7 +262,7 @@ private async Task> GenerateDeploymentRecommendations(Orche
if (!recommendations.Any())
{
var errorMessage = "There are no compatible deployment recommendations for this application.";
- throw new FailedToGenerateAnyRecommendations(errorMessage);
+ throw new FailedToGenerateAnyRecommendations(DeployToolErrorCode.NoCompatibleDeploymentRecipesFound, errorMessage);
}
}
return recommendations;
@@ -276,7 +276,7 @@ private async Task GetSelectedRecommendationFromPreviousDeployme
if (selectedRecommendation == null)
{
var errorMessage = $"{deployedApplication.StackName} already exists as a Cloudformation stack but a compatible recommendation used to perform a re-deployment was not found.";
- throw new FailedToFindCompatibleRecipeException(errorMessage);
+ throw new FailedToFindCompatibleRecipeException(DeployToolErrorCode.CompatibleRecommendationForRedeploymentNotFound, errorMessage);
}
if (!string.IsNullOrEmpty(deploymentSettingRecipeId) && !string.Equals(deploymentSettingRecipeId, selectedRecommendation.Recipe.Id, StringComparison.InvariantCultureIgnoreCase))
{
@@ -286,7 +286,7 @@ private async Task GetSelectedRecommendationFromPreviousDeployme
{
errorMessage += Environment.NewLine + $"The original deployment recipe ID was {deployedApplication.RecipeId} and the current deployment recipe ID is {deploymentSettingRecipeId}";
}
- throw new InvalidUserDeploymentSettingsException(errorMessage.Trim());
+ throw new InvalidUserDeploymentSettingsException(DeployToolErrorCode.StackCreatedFromDifferentDeploymentRecommendation, errorMessage.Trim());
}
selectedRecommendation = selectedRecommendation.ApplyPreviousSettings(existingCloudApplicationMetadata.Settings);
@@ -351,7 +351,7 @@ private async Task GetDeploymentProjectRecipeId(string deploymentProject
}
catch (Exception ex)
{
- throw new FailedToFindDeploymentProjectRecipeIdException($"Failed to find a recipe ID for the deployment project located at {deploymentProjectPath}", ex);
+ throw new FailedToFindDeploymentProjectRecipeIdException(DeployToolErrorCode.FailedToFindDeploymentProjectRecipeId, $"Failed to find a recipe ID for the deployment project located at {deploymentProjectPath}", ex);
}
}
@@ -389,13 +389,13 @@ private void ConfigureDeploymentFromConfigFile(Recommendation recommendation, Us
settingValue = double.Parse(optionSettingValue);
break;
default:
- throw new InvalidOverrideValueException($"Invalid value {optionSettingValue} for option setting item {optionSettingJsonPath}");
+ throw new InvalidOverrideValueException(DeployToolErrorCode.InvalidValueForOptionSettingItem, $"Invalid value {optionSettingValue} for option setting item {optionSettingJsonPath}");
}
}
catch (Exception exception)
{
_toolInteractiveService.WriteDebugLine(exception.PrettyPrint());
- throw new InvalidOverrideValueException($"Invalid value {optionSettingValue} for option setting item {optionSettingJsonPath}");
+ throw new InvalidOverrideValueException(DeployToolErrorCode.InvalidValueForOptionSettingItem, $"Invalid value {optionSettingValue} for option setting item {optionSettingJsonPath}");
}
optionSetting.SetValueOverride(settingValue);
@@ -423,7 +423,7 @@ private void ConfigureDeploymentFromConfigFile(Recommendation recommendation, Us
{
errorMessage += result.ValidationFailedMessage + Environment.NewLine;
}
- throw new InvalidUserDeploymentSettingsException(errorMessage.Trim());
+ throw new InvalidUserDeploymentSettingsException(DeployToolErrorCode.DeploymentConfigurationNeedsAdjusting, errorMessage.Trim());
}
private void SetDeploymentBundleOptionSetting(Recommendation recommendation, string optionSettingId, object settingValue)
@@ -459,7 +459,7 @@ private string GetCloudApplicationName(string? stackName, UserDeploymentSettings
return stackName;
PrintInvalidStackNameMessage();
- throw new InvalidCliArgumentException("Found invalid CLI arguments");
+ throw new InvalidCliArgumentException(DeployToolErrorCode.InvalidCliArguments, "Found invalid CLI arguments");
}
if (!string.IsNullOrEmpty(userDeploymentSettings?.StackName))
@@ -468,14 +468,14 @@ private string GetCloudApplicationName(string? stackName, UserDeploymentSettings
return userDeploymentSettings.StackName;
PrintInvalidStackNameMessage();
- throw new InvalidUserDeploymentSettingsException("Please provide a valid stack name and try again.");
+ throw new InvalidUserDeploymentSettingsException(DeployToolErrorCode.UserDeploymentInvalidStackName, "Please provide a valid stack name and try again.");
}
if (_toolInteractiveService.DisableInteractive)
{
var message = "The \"--silent\" CLI argument can only be used if a CDK stack name is provided either via the CLI argument \"--stack-name\" or through a deployment-settings file. " +
"Please provide a stack name and try again";
- throw new InvalidCliArgumentException(message);
+ throw new InvalidCliArgumentException(DeployToolErrorCode.SilentArgumentNeedsStackNameArgument, message);
}
return AskUserForCloudApplicationName(_session.ProjectDefinition, deployedApplications);
}
@@ -498,7 +498,7 @@ private Recommendation GetSelectedRecommendation(UserDeploymentSettings? userDep
"deployement-settings file or if a path to a custom CDK deployment project is provided via the '--deployment-project' CLI argument." +
$"{Environment.NewLine}Please provide a deployment recipe and try again";
- throw new InvalidCliArgumentException(message);
+ throw new InvalidCliArgumentException(DeployToolErrorCode.SilentArgumentNeedsDeploymentRecipe, message);
}
return _consoleUtilities.AskToChooseRecommendation(recommendations);
}
@@ -506,7 +506,7 @@ private Recommendation GetSelectedRecommendation(UserDeploymentSettings? userDep
var selectedRecommendation = recommendations.FirstOrDefault(x => x.Recipe.Id.Equals(deploymentSettingsRecipeId, StringComparison.Ordinal));
if (selectedRecommendation == null)
{
- throw new InvalidUserDeploymentSettingsException($"The user deployment settings provided contains an invalid value for the property '{nameof(userDeploymentSettings.RecipeId)}'.");
+ throw new InvalidUserDeploymentSettingsException(DeployToolErrorCode.InvalidPropertyValueForUserDeployment, $"The user deployment settings provided contains an invalid value for the property '{nameof(userDeploymentSettings.RecipeId)}'.");
}
_toolInteractiveService.WriteLine();
@@ -602,7 +602,7 @@ private async Task CreateDeploymentBundle(Orchestrator orchestrator, Recommendat
var errorMessage = "Failed to build Docker Image." + Environment.NewLine;
errorMessage += "Docker builds usually fail due to executing them from a working directory that is incompatible with the Dockerfile." + Environment.NewLine;
errorMessage += "Specify a valid Docker execution directory as part of the deployment settings file and try again.";
- throw new DockerBuildFailedException(errorMessage);
+ throw new DockerBuildFailedException(DeployToolErrorCode.DockerBuildFailed, errorMessage);
}
_toolInteractiveService.WriteLine(string.Empty);
@@ -622,7 +622,7 @@ private async Task CreateDeploymentBundle(Orchestrator orchestrator, Recommendat
}
else
{
- throw new FailedToCreateDeploymentBundleException("Failed to create a deployment bundle");
+ throw new FailedToCreateDeploymentBundleException(DeployToolErrorCode.FailedToCreateContainerDeploymentBundle, "Failed to create a deployment bundle");
}
}
}
@@ -630,7 +630,7 @@ private async Task CreateDeploymentBundle(Orchestrator orchestrator, Recommendat
{
var dotnetPublishDeploymentBundleResult = await orchestrator.CreateDotnetPublishDeploymentBundle(selectedRecommendation);
if (!dotnetPublishDeploymentBundleResult)
- throw new FailedToCreateDeploymentBundleException("Failed to create a deployment bundle");
+ throw new FailedToCreateDeploymentBundleException(DeployToolErrorCode.FailedToCreateDotnetPublishDeploymentBundle, "Failed to create a deployment bundle");
}
}
diff --git a/src/AWS.Deploy.CLI/Commands/GenerateDeploymentProjectCommand.cs b/src/AWS.Deploy.CLI/Commands/GenerateDeploymentProjectCommand.cs
index 6e159b05c..2dee18bd2 100644
--- a/src/AWS.Deploy.CLI/Commands/GenerateDeploymentProjectCommand.cs
+++ b/src/AWS.Deploy.CLI/Commands/GenerateDeploymentProjectCommand.cs
@@ -80,7 +80,7 @@ public async Task ExecuteAsync(string saveCdkDirectoryPath, string projectDispla
if (newDirectoryCreated)
_directoryManager.Delete(saveCdkDirectoryPath);
errorMessage = $"Failed to generate deployment project.{Environment.NewLine}{errorMessage}";
- throw new InvalidSaveDirectoryForCdkProject(errorMessage.Trim());
+ throw new InvalidSaveDirectoryForCdkProject(DeployToolErrorCode.InvalidSaveDirectoryForCdkProject, errorMessage.Trim());
}
var directoryUnderSourceControl = await IsDirectoryUnderSourceControl(saveCdkDirectoryPath);
@@ -122,7 +122,7 @@ private async Task> GenerateRecommendationsToSaveDeployment
var recommendations = await orchestrator.GenerateRecommendationsToSaveDeploymentProject();
if (recommendations.Count == 0)
{
- throw new FailedToGenerateAnyRecommendations("The project you are trying to deploy is currently not supported.");
+ throw new FailedToGenerateAnyRecommendations(DeployToolErrorCode.DeploymentProjectNotSupported, "The project you are trying to deploy is currently not supported.");
}
return recommendations;
}
diff --git a/src/AWS.Deploy.CLI/Commands/ServerModeCommand.cs b/src/AWS.Deploy.CLI/Commands/ServerModeCommand.cs
index 1310d42a4..52cc2fb76 100644
--- a/src/AWS.Deploy.CLI/Commands/ServerModeCommand.cs
+++ b/src/AWS.Deploy.CLI/Commands/ServerModeCommand.cs
@@ -39,7 +39,7 @@ public ServerModeCommand(IToolInteractiveService interactiveService, int port, i
IEncryptionProvider encryptionProvider = CreateEncryptionProvider();
if (IsPortInUse(_port))
- throw new TcpPortInUseException("The port you have selected is currently in use by another process.");
+ throw new TcpPortInUseException(DeployToolErrorCode.TcpPortInUse, "The port you have selected is currently in use by another process.");
var url = $"http://localhost:{_port}";
diff --git a/src/AWS.Deploy.CLI/Commands/TypeHints/BeanstalkApplicationCommand.cs b/src/AWS.Deploy.CLI/Commands/TypeHints/BeanstalkApplicationCommand.cs
index 34c58d383..603ec3c75 100644
--- a/src/AWS.Deploy.CLI/Commands/TypeHints/BeanstalkApplicationCommand.cs
+++ b/src/AWS.Deploy.CLI/Commands/TypeHints/BeanstalkApplicationCommand.cs
@@ -57,7 +57,7 @@ public async Task
- [AWSDeploymentExpectedException]
- public class InvalidUserDeploymentSettingsException : Exception
+ public class InvalidUserDeploymentSettingsException : DeployToolException
{
- public InvalidUserDeploymentSettingsException(string message, Exception? innerException = null) : base(message, innerException) { }
+ public InvalidUserDeploymentSettingsException(DeployToolErrorCode errorCode, string message, Exception? innerException = null) : base(errorCode, message, innerException) { }
}
///
/// Exception is thrown if we cannot retrieve deployment bundle definitions
///
- [AWSDeploymentExpectedException]
- public class NoDeploymentBundleDefinitionsFoundException : Exception
+ public class NoDeploymentBundleDefinitionsFoundException : DeployToolException
{
- public NoDeploymentBundleDefinitionsFoundException(string message, Exception? innerException = null) : base(message, innerException) { }
+ public NoDeploymentBundleDefinitionsFoundException(DeployToolErrorCode errorCode, string message, Exception? innerException = null) : base(errorCode, message, innerException) { }
}
/// Exception thrown if a failure occured while trying to update the deployment manifest file.
///
- [AWSDeploymentExpectedException]
- public class FailedToUpdateDeploymentManifestFileException : Exception
+ public class FailedToUpdateDeploymentManifestFileException : DeployToolException
{
- public FailedToUpdateDeploymentManifestFileException(string message, Exception? innerException = null) : base(message, innerException) { }
+ public FailedToUpdateDeploymentManifestFileException(DeployToolErrorCode errorCode, string message, Exception? innerException = null) : base(errorCode, message, innerException) { }
}
- ///
- /// Indicates a specific strongly typed Exception can be anticipated.
- /// Whoever throws this error should also present the user with helpful information
- /// on what wrong and how to fix it. This is the preferred UX.
- ///
- /// Conversely, if an Exceptions not marked with attribute reaches the entry point
- /// application (ie Program.cs) than all exception details will likely be presented to
- /// user.
- ///
- [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
- public class AWSDeploymentExpectedExceptionAttribute : Attribute { }
-
public static class ExceptionExtensions
{
///
- /// True if the is decorated with
- /// .
+ /// True if the inherits from
+ /// .
///
public static bool IsAWSDeploymentExpectedException(this Exception e) =>
- null != e?.GetType()
- .GetCustomAttribute(typeof(AWSDeploymentExpectedExceptionAttribute), inherit: true);
+ e is DeployToolException;
public static string PrettyPrint(this Exception? e)
{
diff --git a/src/AWS.Deploy.Common/ProjectDefinition.cs b/src/AWS.Deploy.Common/ProjectDefinition.cs
index b7282023d..85ea1edf4 100644
--- a/src/AWS.Deploy.Common/ProjectDefinition.cs
+++ b/src/AWS.Deploy.Common/ProjectDefinition.cs
@@ -85,7 +85,7 @@ public ProjectDefinition(
private bool CheckIfDockerFileExists(string projectPath)
{
var dir = Directory.GetFiles(new FileInfo(projectPath).DirectoryName ??
- throw new InvalidProjectPathException("The project path is invalid."), "Dockerfile");
+ throw new InvalidProjectPathException(DeployToolErrorCode.ProjectPathNotFound, "The project path is invalid."), "Dockerfile");
return dir.Length == 1;
}
diff --git a/src/AWS.Deploy.Common/ProjectDefinitionParser.cs b/src/AWS.Deploy.Common/ProjectDefinitionParser.cs
index 31885fd80..ffe5b6043 100644
--- a/src/AWS.Deploy.Common/ProjectDefinitionParser.cs
+++ b/src/AWS.Deploy.Common/ProjectDefinitionParser.cs
@@ -62,7 +62,7 @@ public async Task Parse(string projectPath)
if (!_fileManager.Exists(projectPath))
{
- throw new ProjectFileNotFoundException(projectPath);
+ throw new ProjectFileNotFoundException(DeployToolErrorCode.ProjectPathNotFound, $"A project was not found at the path {projectPath}.");
}
var xmlProjectFile = new XmlDocument();
@@ -73,7 +73,7 @@ public async Task Parse(string projectPath)
projectPath,
await GetProjectSolutionFile(projectPath),
xmlProjectFile.DocumentElement?.Attributes["Sdk"]?.Value ??
- throw new InvalidProjectDefinitionException(
+ throw new InvalidProjectDefinitionException(DeployToolErrorCode.ProjectParserNoSdkAttribute,
"The project file that is being referenced does not contain and 'Sdk' attribute.")
);
diff --git a/src/AWS.Deploy.Common/Recipes/OptionSettingItem.ValueOverride.cs b/src/AWS.Deploy.Common/Recipes/OptionSettingItem.ValueOverride.cs
index bbfa78a9a..1196cb3ce 100644
--- a/src/AWS.Deploy.Common/Recipes/OptionSettingItem.ValueOverride.cs
+++ b/src/AWS.Deploy.Common/Recipes/OptionSettingItem.ValueOverride.cs
@@ -108,11 +108,11 @@ public void SetValueOverride(object valueOverride)
}
}
if (!isValid)
- throw new ValidationFailedException(validationFailedMessage.Trim());
+ throw new ValidationFailedException(DeployToolErrorCode.OptionSettingItemValueValidationFailed, validationFailedMessage.Trim());
if (AllowedValues != null && AllowedValues.Count > 0 && valueOverride != null &&
!AllowedValues.Contains(valueOverride.ToString() ?? ""))
- throw new InvalidOverrideValueException($"Invalid value for option setting item '{Name}'");
+ throw new InvalidOverrideValueException(DeployToolErrorCode.InvalidValueForOptionSettingItem, $"Invalid value for option setting item '{Name}'");
if (valueOverride is bool || valueOverride is int || valueOverride is long || valueOverride is double)
{
diff --git a/src/AWS.Deploy.Common/Recipes/Validation/ValidatorFactory.cs b/src/AWS.Deploy.Common/Recipes/Validation/ValidatorFactory.cs
index 282675fe2..f25c5ae93 100644
--- a/src/AWS.Deploy.Common/Recipes/Validation/ValidatorFactory.cs
+++ b/src/AWS.Deploy.Common/Recipes/Validation/ValidatorFactory.cs
@@ -47,7 +47,7 @@ public static IRecipeValidator[] BuildValidators(this RecipeDefinition recipeDef
{
var validatorInstance = Activator.CreateInstance(typeMappings[validatorType]);
if (validatorInstance == null)
- throw new InvalidValidatorTypeException($"Could not create an instance of validator type {validatorType}");
+ throw new InvalidValidatorTypeException(DeployToolErrorCode.UnableToCreateValidatorInstance, $"Could not create an instance of validator type {validatorType}");
return validatorInstance;
}
@@ -55,7 +55,7 @@ public static IRecipeValidator[] BuildValidators(this RecipeDefinition recipeDef
{
var validatorInstance = jObject.ToObject(typeMappings[validatorType]);
if (validatorInstance == null)
- throw new InvalidValidatorTypeException($"Could not create an instance of validator type {validatorType}");
+ throw new InvalidValidatorTypeException(DeployToolErrorCode.UnableToCreateValidatorInstance, $"Could not create an instance of validator type {validatorType}");
return validatorInstance;
}
diff --git a/src/AWS.Deploy.Common/Recommendation.cs b/src/AWS.Deploy.Common/Recommendation.cs
index d23caf2d1..c30c2f5a2 100644
--- a/src/AWS.Deploy.Common/Recommendation.cs
+++ b/src/AWS.Deploy.Common/Recommendation.cs
@@ -98,7 +98,7 @@ public IEnumerable GetConfigurableOptionSettingItems()
public OptionSettingItem GetOptionSetting(string? jsonPath)
{
if (string.IsNullOrEmpty(jsonPath))
- throw new OptionSettingItemDoesNotExistException($"The Option Setting Item {jsonPath} does not exist as part of the" +
+ throw new OptionSettingItemDoesNotExistException(DeployToolErrorCode.OptionSettingItemDoesNotExistInRecipe, $"The Option Setting Item {jsonPath} does not exist as part of the" +
$" {Recipe.Name} recipe");
var ids = jsonPath.Split('.');
@@ -110,7 +110,7 @@ public OptionSettingItem GetOptionSetting(string? jsonPath)
optionSetting = optionSettings.FirstOrDefault(os => os.Id.Equals(id));
if (optionSetting == null)
{
- throw new OptionSettingItemDoesNotExistException($"The Option Setting Item {jsonPath} does not exist as part of the" +
+ throw new OptionSettingItemDoesNotExistException(DeployToolErrorCode.OptionSettingItemDoesNotExistInRecipe, $"The Option Setting Item {jsonPath} does not exist as part of the" +
$" {Recipe.Name} recipe");
}
}
diff --git a/src/AWS.Deploy.Common/UserDeploymentSettings.cs b/src/AWS.Deploy.Common/UserDeploymentSettings.cs
index ccaaa0620..6b94aa81c 100644
--- a/src/AWS.Deploy.Common/UserDeploymentSettings.cs
+++ b/src/AWS.Deploy.Common/UserDeploymentSettings.cs
@@ -42,7 +42,7 @@ public class UserDeploymentSettings
}
catch (Exception ex)
{
- throw new InvalidUserDeploymentSettingsException("An error occured while trying to deserialize the User Deployment Settings file.", ex);
+ throw new InvalidUserDeploymentSettingsException(DeployToolErrorCode.FailedToDeserializeUserDeploymentFile, "An error occured while trying to deserialize the User Deployment Settings file.", ex);
}
}
diff --git a/src/AWS.Deploy.DockerEngine/DockerEngine.cs b/src/AWS.Deploy.DockerEngine/DockerEngine.cs
index 140478a28..aa12ba2ec 100644
--- a/src/AWS.Deploy.DockerEngine/DockerEngine.cs
+++ b/src/AWS.Deploy.DockerEngine/DockerEngine.cs
@@ -56,7 +56,7 @@ public void GenerateDockerFile()
var imageMapping = GetImageMapping();
if (imageMapping == null)
{
- throw new UnknownDockerImageException($"Unable to determine a valid docker base and build image for project of type {_project.SdkType} and Target Framework {_project.TargetFramework}");
+ throw new UnknownDockerImageException(DeployToolErrorCode.NoValidDockerImageForProject, $"Unable to determine a valid docker base and build image for project of type {_project.SdkType} and Target Framework {_project.TargetFramework}");
}
var dockerFile = new DockerFile(imageMapping, projectFileName, _project.AssemblyName);
@@ -131,10 +131,10 @@ private ImageMapping GetImageMapping()
var definitions = JsonConvert.DeserializeObject>(content);
var mappings = definitions.FirstOrDefault(x => x.SdkType.Equals(_project.SdkType));
if (mappings == null)
- throw new UnsupportedProjectException($"The project with SDK Type {_project.SdkType} is not supported.");
+ throw new UnsupportedProjectException(DeployToolErrorCode.NoValidDockerMappingForSdkType, $"The project with SDK Type {_project.SdkType} is not supported.");
return mappings.ImageMapping.FirstOrDefault(x => x.TargetFramework.Equals(_project.TargetFramework))
- ?? throw new UnsupportedProjectException($"The project with Target Framework {_project.TargetFramework} is not supported.");
+ ?? throw new UnsupportedProjectException(DeployToolErrorCode.NoValidDockerMappingForTargetFramework, $"The project with Target Framework {_project.TargetFramework} is not supported.");
}
///
diff --git a/src/AWS.Deploy.DockerEngine/Exceptions.cs b/src/AWS.Deploy.DockerEngine/Exceptions.cs
index d844c066a..52de5da32 100644
--- a/src/AWS.Deploy.DockerEngine/Exceptions.cs
+++ b/src/AWS.Deploy.DockerEngine/Exceptions.cs
@@ -2,31 +2,32 @@
// SPDX-License-Identifier: Apache-2.0
using System;
+using AWS.Deploy.Common;
namespace AWS.Deploy.DockerEngine
{
public class DockerFileTemplateException : DockerEngineExceptionBase
{
- public DockerFileTemplateException(string message) : base(message) { }
+ public DockerFileTemplateException(DeployToolErrorCode errorCode, string message) : base(errorCode, message) { }
}
public class DockerEngineException : DockerEngineExceptionBase
{
- public DockerEngineException(string message) : base(message) { }
+ public DockerEngineException(DeployToolErrorCode errorCode, string message) : base(errorCode, message) { }
}
public class UnknownDockerImageException : DockerEngineExceptionBase
{
- public UnknownDockerImageException(string message) : base(message) { }
+ public UnknownDockerImageException(DeployToolErrorCode errorCode, string message) : base(errorCode, message) { }
}
- public class DockerEngineExceptionBase : Exception
+ public class DockerEngineExceptionBase : DeployToolException
{
- public DockerEngineExceptionBase(string message) : base(message) { }
+ public DockerEngineExceptionBase(DeployToolErrorCode errorCode, string message) : base(errorCode, message) { }
}
public class UnsupportedProjectException : DockerEngineExceptionBase
{
- public UnsupportedProjectException(string message) : base(message) { }
+ public UnsupportedProjectException(DeployToolErrorCode errorCode, string message) : base(errorCode, message) { }
}
}
diff --git a/src/AWS.Deploy.DockerEngine/ProjectUtilities.cs b/src/AWS.Deploy.DockerEngine/ProjectUtilities.cs
index 70ba5a01b..79946b4f6 100644
--- a/src/AWS.Deploy.DockerEngine/ProjectUtilities.cs
+++ b/src/AWS.Deploy.DockerEngine/ProjectUtilities.cs
@@ -3,6 +3,7 @@
using System.IO;
using System.Reflection;
+using AWS.Deploy.Common;
using AWS.Deploy.Common.Extensions;
namespace AWS.Deploy.DockerEngine
@@ -21,7 +22,7 @@ internal static string ReadDockerFileConfig()
if (string.IsNullOrWhiteSpace(template))
{
- throw new DockerEngineException($"The DockerEngine could not find the embedded config file responsible for mapping projects to Docker images.");
+ throw new DockerEngineException(DeployToolErrorCode.UnableToMapProjectToDockerImage, $"The DockerEngine could not find the embedded config file responsible for mapping projects to Docker images.");
}
return template;
@@ -36,7 +37,7 @@ internal static string ReadTemplate()
if (string.IsNullOrWhiteSpace(template))
{
- throw new DockerFileTemplateException("The Dockerfile template for the project was not found.");
+ throw new DockerFileTemplateException(DeployToolErrorCode.DockerFileTemplateNotFound, "The Dockerfile template for the project was not found.");
}
return template;
diff --git a/src/AWS.Deploy.Orchestration/CDK/CDKInstaller.cs b/src/AWS.Deploy.Orchestration/CDK/CDKInstaller.cs
index d6e59f159..65e9985ba 100644
--- a/src/AWS.Deploy.Orchestration/CDK/CDKInstaller.cs
+++ b/src/AWS.Deploy.Orchestration/CDK/CDKInstaller.cs
@@ -5,6 +5,7 @@
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using AWS.Deploy.Common;
using AWS.Deploy.Orchestration.Utilities;
namespace AWS.Deploy.Orchestration.CDK
@@ -52,7 +53,7 @@ public async Task> GetVersion(string workingDirectory)
}
catch (Exception exception)
{
- throw new NPMCommandFailedException($"Failed to execute {command}", exception);
+ throw new NPMCommandFailedException(DeployToolErrorCode.FailedToGetCDKVersion, $"Failed to execute {command}", exception);
}
var standardOut = result.StandardOut ?? "";
diff --git a/src/AWS.Deploy.Orchestration/CDK/NPMPackageInitializer.cs b/src/AWS.Deploy.Orchestration/CDK/NPMPackageInitializer.cs
index c5759a294..1ced1fd2a 100644
--- a/src/AWS.Deploy.Orchestration/CDK/NPMPackageInitializer.cs
+++ b/src/AWS.Deploy.Orchestration/CDK/NPMPackageInitializer.cs
@@ -4,6 +4,7 @@
using System;
using System.IO;
using System.Threading.Tasks;
+using AWS.Deploy.Common;
using AWS.Deploy.Common.IO;
using AWS.Deploy.Orchestration.Utilities;
@@ -85,7 +86,7 @@ public async Task Initialize(string workingDirectory, Version cdkVersion)
}
catch (Exception exception)
{
- throw new PackageJsonFileException($"Failed to write {_packageJsonFileName} at {packageJsonFilePath}", exception);
+ throw new PackageJsonFileException(DeployToolErrorCode.FailedToWritePackageJsonFile, $"Failed to write {_packageJsonFileName} at {packageJsonFilePath}", exception);
}
try
@@ -95,7 +96,7 @@ public async Task Initialize(string workingDirectory, Version cdkVersion)
}
catch (Exception exception)
{
- throw new NPMCommandFailedException($"Failed to install npm packages at {workingDirectory}", exception);
+ throw new NPMCommandFailedException(DeployToolErrorCode.FailedToInstallNpmPackages, $"Failed to install npm packages at {workingDirectory}", exception);
}
}
}
diff --git a/src/AWS.Deploy.Orchestration/CdkAppSettingsSerializer.cs b/src/AWS.Deploy.Orchestration/CdkAppSettingsSerializer.cs
index 48e1d0d48..f9e55467b 100644
--- a/src/AWS.Deploy.Orchestration/CdkAppSettingsSerializer.cs
+++ b/src/AWS.Deploy.Orchestration/CdkAppSettingsSerializer.cs
@@ -15,7 +15,7 @@ public string Build(CloudApplication cloudApplication, Recommendation recommenda
{
var projectPath = new FileInfo(recommendation.ProjectPath).Directory?.FullName;
if (string.IsNullOrEmpty(projectPath))
- throw new InvalidProjectPathException("The project path provided is invalid.");
+ throw new InvalidProjectPathException(DeployToolErrorCode.ProjectPathNotFound, "The project path provided is invalid.");
// General Settings
var appSettingsContainer = new RecipeProps>(
diff --git a/src/AWS.Deploy.Orchestration/CdkProjectHandler.cs b/src/AWS.Deploy.Orchestration/CdkProjectHandler.cs
index b8a7f680c..6ab89ac1a 100644
--- a/src/AWS.Deploy.Orchestration/CdkProjectHandler.cs
+++ b/src/AWS.Deploy.Orchestration/CdkProjectHandler.cs
@@ -87,7 +87,7 @@ await _commandLineWrapper.Run($"npx cdk bootstrap aws://{session.AWSAccountId}/{
streamOutputToInteractiveService: true);
if (cdkDeploy.ExitCode != 0)
- throw new FailedToDeployCDKAppException("We had an issue deploying your application to AWS. Check the deployment output for more details.");
+ throw new FailedToDeployCDKAppException(DeployToolErrorCode.FailedToDeployCdkApplication, "We had an issue deploying your application to AWS. Check the deployment output for more details.");
}
public string CreateCdkProject(Recommendation recommendation, OrchestratorSession session, string? saveCdkDirectoryPath = null)
diff --git a/src/AWS.Deploy.Orchestration/Data/AWSResourceQueryer.cs b/src/AWS.Deploy.Orchestration/Data/AWSResourceQueryer.cs
index 79d25f262..df5f30ab4 100644
--- a/src/AWS.Deploy.Orchestration/Data/AWSResourceQueryer.cs
+++ b/src/AWS.Deploy.Orchestration/Data/AWSResourceQueryer.cs
@@ -89,7 +89,7 @@ public AWSResourceQueryer(IAWSClientFactory awsClientFactory)
if (service == null)
{
- throw new AWSResourceNotFoundException($"The AppRunner service '{serviceArn}' does not exist.");
+ throw new AWSResourceNotFoundException(DeployToolErrorCode.AppRunnerServiceDoesNotExist, $"The AppRunner service '{serviceArn}' does not exist.");
}
return service;
@@ -113,7 +113,7 @@ public async Task DescribeElasticBeanstalkEnvironment(st
if (!environment.Environments.Any())
{
- throw new AWSResourceNotFoundException($"The elastic beanstalk environment '{environmentId}' does not exist.");
+ throw new AWSResourceNotFoundException(DeployToolErrorCode.BeanstalkEnvironmentDoesNotExist, $"The elastic beanstalk environment '{environmentId}' does not exist.");
}
return environment.Environments.First();
@@ -130,7 +130,7 @@ public async Task DescribeElasticBeanstalkEnvironment(st
if (!loadBalancers.LoadBalancers.Any())
{
- throw new AWSResourceNotFoundException($"The load balancer '{loadBalancerArn}' does not exist.");
+ throw new AWSResourceNotFoundException(DeployToolErrorCode.LoadBalancerDoesNotExist, $"The load balancer '{loadBalancerArn}' does not exist.");
}
return loadBalancers.LoadBalancers.First();
@@ -147,7 +147,7 @@ public async Task DescribeElasticBeanstalkEnvironment(st
if (!listeners.Listeners.Any())
{
- throw new AWSResourceNotFoundException($"The load balancer '{loadBalancerArn}' does not have any listeners.");
+ throw new AWSResourceNotFoundException(DeployToolErrorCode.LoadBalancerListenerDoesNotExist, $"The load balancer '{loadBalancerArn}' does not have any listeners.");
}
return listeners.Listeners;
@@ -164,7 +164,7 @@ public async Task DescribeCloudWatchRule(string ruleName)
if (rule == null)
{
- throw new AWSResourceNotFoundException($"The CloudWatch rule'{ruleName}' does not exist.");
+ throw new AWSResourceNotFoundException(DeployToolErrorCode.CloudWatchRuleDoesNotExist, $"The CloudWatch rule'{ruleName}' does not exist.");
}
return rule;
diff --git a/src/AWS.Deploy.Orchestration/DeploymentBundleHandler.cs b/src/AWS.Deploy.Orchestration/DeploymentBundleHandler.cs
index de1dc8324..18e3f88b0 100644
--- a/src/AWS.Deploy.Orchestration/DeploymentBundleHandler.cs
+++ b/src/AWS.Deploy.Orchestration/DeploymentBundleHandler.cs
@@ -65,7 +65,7 @@ public async Task BuildDockerImage(CloudApplication cloudApplication, Re
var result = await _commandLineWrapper.TryRunWithResult(dockerBuildCommand, dockerExecutionDirectory, streamOutputToInteractiveService: true);
if (result.ExitCode != 0)
{
- throw new DockerBuildFailedException(result.StandardError ?? "");
+ throw new DockerBuildFailedException(DeployToolErrorCode.DockerBuildFailed, result.StandardError ?? "");
}
return imageTag;
@@ -120,7 +120,7 @@ public async Task CreateDotnetPublishZip(Recommendation recommendation)
var result = await _commandLineWrapper.TryRunWithResult(publishCommand, streamOutputToInteractiveService: true);
if (result.ExitCode != 0)
{
- throw new DotnetPublishFailedException(result.StandardError ?? "");
+ throw new DotnetPublishFailedException(DeployToolErrorCode.DotnetPublishFailed, result.StandardError ?? "");
}
var zipFilePath = $"{publishDirectoryInfo.FullName}.zip";
@@ -143,7 +143,7 @@ private string GetDockerExecutionDirectory(Recommendation recommendation)
var dockerExecutionDirectory = recommendation.DeploymentBundle.DockerExecutionDirectory;
var dockerFileDirectory = new FileInfo(recommendation.ProjectPath).Directory?.FullName;
if (dockerFileDirectory == null)
- throw new InvalidProjectPathException("The project path is invalid.");
+ throw new InvalidProjectPathException(DeployToolErrorCode.ProjectPathNotFound, "The project path is invalid.");
var projectSolutionPath = recommendation.ProjectDefinition.ProjectSolutionPath;
if (string.IsNullOrEmpty(dockerExecutionDirectory))
@@ -155,7 +155,7 @@ private string GetDockerExecutionDirectory(Recommendation recommendation)
else
{
var projectSolutionDirectory = new FileInfo(projectSolutionPath).Directory?.FullName;
- dockerExecutionDirectory = projectSolutionDirectory ?? throw new InvalidSolutionPathException("The solution path is invalid.");
+ dockerExecutionDirectory = projectSolutionDirectory ?? throw new InvalidSolutionPathException(DeployToolErrorCode.InvalidSolutionPath, "The solution path is invalid.");
}
}
@@ -166,7 +166,7 @@ private string GetDockerFilePath(Recommendation recommendation)
{
var dockerFileDirectory = new FileInfo(recommendation.ProjectPath).Directory?.FullName;
if (dockerFileDirectory == null)
- throw new InvalidProjectPathException("The project path is invalid.");
+ throw new InvalidProjectPathException(DeployToolErrorCode.ProjectPathNotFound, "The project path is invalid.");
return Path.Combine(dockerFileDirectory, "Dockerfile");
}
@@ -195,7 +195,7 @@ private async Task InitiateDockerLogin()
var authorizationTokens = await _awsResourceQueryer.GetECRAuthorizationToken();
if (authorizationTokens.Count == 0)
- throw new DockerLoginFailedException("Failed to login to Docker");
+ throw new DockerLoginFailedException(DeployToolErrorCode.DockerLoginFailed, "Failed to login to Docker");
var authTokenBytes = Convert.FromBase64String(authorizationTokens[0].AuthorizationToken);
var authToken = Encoding.UTF8.GetString(authTokenBytes);
@@ -205,7 +205,7 @@ private async Task InitiateDockerLogin()
var result = await _commandLineWrapper.TryRunWithResult(dockerLoginCommand, streamOutputToInteractiveService: true);
if (result.ExitCode != 0)
- throw new DockerLoginFailedException("Failed to login to Docker");
+ throw new DockerLoginFailedException(DeployToolErrorCode.DockerLoginFailed, "Failed to login to Docker");
}
private async Task SetupECRRepository(string ecrRepositoryName)
@@ -228,7 +228,7 @@ private async Task TagDockerImage(string sourceTagName, string targetTagName)
var result = await _commandLineWrapper.TryRunWithResult(dockerTagCommand, streamOutputToInteractiveService: true);
if (result.ExitCode != 0)
- throw new DockerTagFailedException("Failed to tag Docker image");
+ throw new DockerTagFailedException(DeployToolErrorCode.DockerTagFailed, "Failed to tag Docker image");
}
private async Task PushDockerImage(string targetTagName)
@@ -237,7 +237,7 @@ private async Task PushDockerImage(string targetTagName)
var result = await _commandLineWrapper.TryRunWithResult(dockerPushCommand, streamOutputToInteractiveService: true);
if (result.ExitCode != 0)
- throw new DockerPushFailedException("Failed to push Docker Image");
+ throw new DockerPushFailedException(DeployToolErrorCode.DockerPushFailed, "Failed to push Docker Image");
}
}
}
diff --git a/src/AWS.Deploy.Orchestration/Exceptions.cs b/src/AWS.Deploy.Orchestration/Exceptions.cs
index 345990dab..b4acc3822 100644
--- a/src/AWS.Deploy.Orchestration/Exceptions.cs
+++ b/src/AWS.Deploy.Orchestration/Exceptions.cs
@@ -7,189 +7,168 @@ namespace AWS.Deploy.Orchestration
///
/// Exception is thrown if Microsoft Templating Engine is unable to generate a template
///
- [AWSDeploymentExpectedException]
- public class TemplateGenerationFailedException : Exception
+ public class TemplateGenerationFailedException : DeployToolException
{
- public TemplateGenerationFailedException(string message, Exception? innerException = null) : base(message, innerException) { }
+ public TemplateGenerationFailedException(DeployToolErrorCode errorCode, string message, Exception? innerException = null) : base(errorCode, message, innerException) { }
}
///
/// Exception is thrown if Microsoft Templating Engine is unable to find location to install templates from
///
- [AWSDeploymentExpectedException]
- public class DefaultTemplateInstallationFailedException : Exception
+ public class DefaultTemplateInstallationFailedException : DeployToolException
{
- public DefaultTemplateInstallationFailedException(string message, Exception? innerException = null) : base(message, innerException) { }
+ public DefaultTemplateInstallationFailedException(DeployToolErrorCode errorCode, string message, Exception? innerException = null) : base(errorCode, message, innerException) { }
}
///
/// Exception is thrown if Microsoft Templating Engine returns an error when running a command
///
- [AWSDeploymentExpectedException]
- public class RunCommandFailedException : Exception
+ public class RunCommandFailedException : DeployToolException
{
- public RunCommandFailedException(string message, Exception? innerException = null) : base(message, innerException) { }
+ public RunCommandFailedException(DeployToolErrorCode errorCode, string message, Exception? innerException = null) : base(errorCode, message, innerException) { }
}
///
/// Exception is thrown if package.json file IO fails.
///
- [AWSDeploymentExpectedException]
- public class PackageJsonFileException : Exception
+ public class PackageJsonFileException : DeployToolException
{
- public PackageJsonFileException(string message, Exception? innerException = null) : base(message, innerException) { }
+ public PackageJsonFileException(DeployToolErrorCode errorCode, string message, Exception? innerException = null) : base(errorCode, message, innerException) { }
}
///
/// Exception is thrown if docker build attempt failed
///
- [AWSDeploymentExpectedException]
- public class DockerBuildFailedException : Exception
+ public class DockerBuildFailedException : DeployToolException
{
- public DockerBuildFailedException(string message, Exception? innerException = null) : base(message, innerException) { }
+ public DockerBuildFailedException(DeployToolErrorCode errorCode, string message, Exception? innerException = null) : base(errorCode, message, innerException) { }
}
///
/// Exception is thrown if npm command fails to execute.
///
- [AWSDeploymentExpectedException]
- public class NPMCommandFailedException : Exception
+ public class NPMCommandFailedException : DeployToolException
{
- public NPMCommandFailedException(string message, Exception? innerException = null) : base(message, innerException) { }
+ public NPMCommandFailedException(DeployToolErrorCode errorCode, string message, Exception? innerException = null) : base(errorCode, message, innerException) { }
}
///
/// Exception is thrown if docker login attempt failed
///
- [AWSDeploymentExpectedException]
- public class DockerLoginFailedException : Exception
+ public class DockerLoginFailedException : DeployToolException
{
- public DockerLoginFailedException(string message, Exception? innerException = null) : base(message, innerException) { }
+ public DockerLoginFailedException(DeployToolErrorCode errorCode, string message, Exception? innerException = null) : base(errorCode, message, innerException) { }
}
///
/// Exception is thrown if docker tag attempt failed
///
- [AWSDeploymentExpectedException]
- public class DockerTagFailedException : Exception
+ public class DockerTagFailedException : DeployToolException
{
- public DockerTagFailedException(string message, Exception? innerException = null) : base(message, innerException) { }
+ public DockerTagFailedException(DeployToolErrorCode errorCode, string message, Exception? innerException = null) : base(errorCode, message, innerException) { }
}
///
/// Exception is thrown if docker push attempt failed
///
- [AWSDeploymentExpectedException]
- public class DockerPushFailedException : Exception
+ public class DockerPushFailedException : DeployToolException
{
- public DockerPushFailedException(string message, Exception? innerException = null) : base(message, innerException) { }
+ public DockerPushFailedException(DeployToolErrorCode errorCode, string message, Exception? innerException = null) : base(errorCode, message, innerException) { }
}
///
/// Exception is thrown if we cannot retrieve recipe definitions
///
- [AWSDeploymentExpectedException]
- public class NoRecipeDefinitionsFoundException : Exception
+ public class NoRecipeDefinitionsFoundException : DeployToolException
{
- public NoRecipeDefinitionsFoundException(string message, Exception? innerException = null) : base(message, innerException) { }
+ public NoRecipeDefinitionsFoundException(DeployToolErrorCode errorCode, string message, Exception? innerException = null) : base(errorCode, message, innerException) { }
}
///
/// Exception is thrown if dotnet publish attempt failed
///
- [AWSDeploymentExpectedException]
- public class DotnetPublishFailedException : Exception
+ public class DotnetPublishFailedException : DeployToolException
{
- public DotnetPublishFailedException(string message, Exception? innerException = null) : base(message, innerException) { }
+ public DotnetPublishFailedException(DeployToolErrorCode errorCode, string message, Exception? innerException = null) : base(errorCode, message, innerException) { }
}
///
/// Throw if Zip File Manager fails to create a Zip File
///
- [AWSDeploymentExpectedException]
- public class FailedToCreateZipFileException : Exception
+ public class FailedToCreateZipFileException : DeployToolException
{
- public FailedToCreateZipFileException(string message, Exception? innerException = null) : base(message, innerException) { }
+ public FailedToCreateZipFileException(DeployToolErrorCode errorCode, string message, Exception? innerException = null) : base(errorCode, message, innerException) { }
}
///
/// Exception thrown if Docker file could not be generated
///
- [AWSDeploymentExpectedException]
- public class FailedToGenerateDockerFileException : Exception
+ public class FailedToGenerateDockerFileException : DeployToolException
{
- public FailedToGenerateDockerFileException(string message, Exception? innerException = null) : base(message, innerException) { }
+ public FailedToGenerateDockerFileException(DeployToolErrorCode errorCode, string message, Exception? innerException = null) : base(errorCode, message, innerException) { }
}
///
/// Exception thrown if RecipePath contains an invalid path
///
- [AWSDeploymentExpectedException]
- public class InvalidRecipePathException : Exception
+ public class InvalidRecipePathException : DeployToolException
{
- public InvalidRecipePathException(string message, Exception? innerException = null) : base(message, innerException) { }
+ public InvalidRecipePathException(DeployToolErrorCode errorCode, string message, Exception? innerException = null) : base(errorCode, message, innerException) { }
}
///
/// Exception thrown if Solution Path contains an invalid path
///
- [AWSDeploymentExpectedException]
- public class InvalidSolutionPathException : Exception
+ public class InvalidSolutionPathException : DeployToolException
{
- public InvalidSolutionPathException(string message, Exception? innerException = null) : base(message, innerException) { }
+ public InvalidSolutionPathException(DeployToolErrorCode errorCode, string message, Exception? innerException = null) : base(errorCode, message, innerException) { }
}
///
/// Exception thrown if AWS Deploy Recipes CDK Common Product Version is invalid.
///
- [AWSDeploymentExpectedException]
- public class InvalidAWSDeployRecipesCDKCommonVersionException : Exception
+ public class InvalidAWSDeployRecipesCDKCommonVersionException : DeployToolException
{
- public InvalidAWSDeployRecipesCDKCommonVersionException(string message, Exception? innerException = null) : base(message, innerException) { }
+ public InvalidAWSDeployRecipesCDKCommonVersionException(DeployToolErrorCode errorCode, string message, Exception? innerException = null) : base(errorCode, message, innerException) { }
}
///
/// Exception thrown if the 'cdk deploy' command failed.
///
- [AWSDeploymentExpectedException]
- public class FailedToDeployCDKAppException : Exception
+ public class FailedToDeployCDKAppException : DeployToolException
{
- public FailedToDeployCDKAppException(string message, Exception? innerException = null) : base(message, innerException) { }
+ public FailedToDeployCDKAppException(DeployToolErrorCode errorCode, string message, Exception? innerException = null) : base(errorCode, message, innerException) { }
}
///
/// Exception thrown if an AWS Resource is not found or does not exist.
///
- [AWSDeploymentExpectedException]
- public class AWSResourceNotFoundException : Exception
+ public class AWSResourceNotFoundException : DeployToolException
{
- public AWSResourceNotFoundException(string message, Exception? innerException = null) : base(message, innerException) { }
+ public AWSResourceNotFoundException(DeployToolErrorCode errorCode, string message, Exception? innerException = null) : base(errorCode, message, innerException) { }
}
///
/// Exception thrown if the Local User Settings File is invalid.
///
- [AWSDeploymentExpectedException]
- public class InvalidLocalUserSettingsFileException : Exception
+ public class InvalidLocalUserSettingsFileException : DeployToolException
{
- public InvalidLocalUserSettingsFileException(string message, Exception? innerException = null) : base(message, innerException) { }
+ public InvalidLocalUserSettingsFileException(DeployToolErrorCode errorCode, string message, Exception? innerException = null) : base(errorCode, message, innerException) { }
}
///
/// Exception thrown if a failure occured while trying to update the Local User Settings file.
///
- [AWSDeploymentExpectedException]
- public class FailedToUpdateLocalUserSettingsFileException : Exception
+ public class FailedToUpdateLocalUserSettingsFileException : DeployToolException
{
- public FailedToUpdateLocalUserSettingsFileException(string message, Exception? innerException = null) : base(message, innerException) { }
+ public FailedToUpdateLocalUserSettingsFileException(DeployToolErrorCode errorCode, string message, Exception? innerException = null) : base(errorCode, message, innerException) { }
}
///
/// Throw if docker info failed to return output.
///
- [AWSDeploymentExpectedException]
- public class DockerInfoException : Exception
+ public class DockerInfoException : DeployToolException
{
- public DockerInfoException(string message, Exception? innerException = null) : base(message, innerException) { }
+ public DockerInfoException(DeployToolErrorCode errorCode, string message, Exception? innerException = null) : base(errorCode, message, innerException) { }
}
}
diff --git a/src/AWS.Deploy.Orchestration/LocalUserSettings/LocalUserSettingsEngine.cs b/src/AWS.Deploy.Orchestration/LocalUserSettings/LocalUserSettingsEngine.cs
index 8203333cb..502aa578d 100644
--- a/src/AWS.Deploy.Orchestration/LocalUserSettings/LocalUserSettingsEngine.cs
+++ b/src/AWS.Deploy.Orchestration/LocalUserSettings/LocalUserSettingsEngine.cs
@@ -42,9 +42,9 @@ public async Task UpdateLastDeployedStack(string stackName, string projectName,
try
{
if (string.IsNullOrEmpty(projectName))
- throw new FailedToUpdateLocalUserSettingsFileException("The Project Name is not defined.");
+ throw new FailedToUpdateLocalUserSettingsFileException(DeployToolErrorCode.FailedToUpdateLocalUserSettingsFile, "The Project Name is not defined.");
if (string.IsNullOrEmpty(awsAccountId) || string.IsNullOrEmpty(awsRegion))
- throw new FailedToUpdateLocalUserSettingsFileException("The AWS Account Id or Region is not defined.");
+ throw new FailedToUpdateLocalUserSettingsFileException(DeployToolErrorCode.FailedToUpdateLocalUserSettingsFile, "The AWS Account Id or Region is not defined.");
var localUserSettings = await GetLocalUserSettings();
var lastDeployedStack = localUserSettings?.LastDeployedStacks?
@@ -105,7 +105,7 @@ public async Task UpdateLastDeployedStack(string stackName, string projectName,
}
catch (Exception ex)
{
- throw new FailedToUpdateLocalUserSettingsFileException($"Failed to update the local user settings file " +
+ throw new FailedToUpdateLocalUserSettingsFileException(DeployToolErrorCode.FailedToUpdateLocalUserSettingsFile, $"Failed to update the local user settings file " +
$"to include the last deployed to stack '{stackName}'.", ex);
}
}
@@ -118,9 +118,9 @@ public async Task DeleteLastDeployedStack(string stackName, string projectName,
try
{
if (string.IsNullOrEmpty(projectName))
- throw new FailedToUpdateLocalUserSettingsFileException("The Project Name is not defined.");
+ throw new FailedToUpdateLocalUserSettingsFileException(DeployToolErrorCode.FailedToUpdateLocalUserSettingsFile, "The Project Name is not defined.");
if (string.IsNullOrEmpty(awsAccountId) || string.IsNullOrEmpty(awsRegion))
- throw new FailedToUpdateLocalUserSettingsFileException("The AWS Account Id or Region is not defined.");
+ throw new FailedToUpdateLocalUserSettingsFileException(DeployToolErrorCode.FailedToUpdateLocalUserSettingsFile, "The AWS Account Id or Region is not defined.");
var localUserSettings = await GetLocalUserSettings();
var lastDeployedStack = localUserSettings?.LastDeployedStacks?
@@ -135,7 +135,7 @@ public async Task DeleteLastDeployedStack(string stackName, string projectName,
}
catch (Exception ex)
{
- throw new FailedToUpdateLocalUserSettingsFileException($"Failed to update the local user settings file " +
+ throw new FailedToUpdateLocalUserSettingsFileException(DeployToolErrorCode.FailedToUpdateLocalUserSettingsFile, $"Failed to update the local user settings file " +
$"to delete the stack '{stackName}'.", ex);
}
}
@@ -148,9 +148,9 @@ public async Task CleanOrphanStacks(List deployedStacks, string projectN
try
{
if (string.IsNullOrEmpty(projectName))
- throw new FailedToUpdateLocalUserSettingsFileException("The Project Name is not defined.");
+ throw new FailedToUpdateLocalUserSettingsFileException(DeployToolErrorCode.FailedToUpdateLocalUserSettingsFile, "The Project Name is not defined.");
if (string.IsNullOrEmpty(awsAccountId) || string.IsNullOrEmpty(awsRegion))
- throw new FailedToUpdateLocalUserSettingsFileException("The AWS Account Id or Region is not defined.");
+ throw new FailedToUpdateLocalUserSettingsFileException(DeployToolErrorCode.FailedToUpdateLocalUserSettingsFile, "The AWS Account Id or Region is not defined.");
var localUserSettings = await GetLocalUserSettings();
var localStacks = localUserSettings?.LastDeployedStacks?
@@ -167,7 +167,7 @@ public async Task CleanOrphanStacks(List deployedStacks, string projectN
}
catch (Exception ex)
{
- throw new FailedToUpdateLocalUserSettingsFileException($"Failed to update the local user settings file " +
+ throw new FailedToUpdateLocalUserSettingsFileException(DeployToolErrorCode.FailedToUpdateLocalUserSettingsFile, $"Failed to update the local user settings file " +
$"to delete orphan stacks.", ex);
}
}
@@ -204,7 +204,7 @@ private async Task WriteLocalUserSettingsFile(LocalUserSettings deployme
}
catch (Exception ex)
{
- throw new InvalidLocalUserSettingsFileException("The Local User Settings file is invalid.", ex);
+ throw new InvalidLocalUserSettingsFileException(DeployToolErrorCode.InvalidLocalUserSettingsFile, "The Local User Settings file is invalid.", ex);
}
}
diff --git a/src/AWS.Deploy.Orchestration/Orchestrator.cs b/src/AWS.Deploy.Orchestration/Orchestrator.cs
index b24fe7cd0..9b60caf92 100644
--- a/src/AWS.Deploy.Orchestration/Orchestrator.cs
+++ b/src/AWS.Deploy.Orchestration/Orchestrator.cs
@@ -107,7 +107,7 @@ public async Task> GenerateRecommendationsFromSavedDeployme
if (_directoryManager == null)
throw new InvalidOperationException($"{nameof(_directoryManager)} is null as part of the orchestartor object");
if (!_directoryManager.Exists(deploymentProjectPath))
- throw new InvalidCliArgumentException($"The path '{deploymentProjectPath}' does not exists on the file system. Please provide a valid deployment project path and try again.");
+ throw new InvalidCliArgumentException(DeployToolErrorCode.DeploymentProjectPathNotFound, $"The path '{deploymentProjectPath}' does not exists on the file system. Please provide a valid deployment project path and try again.");
var engine = new RecommendationEngine.RecommendationEngine(new List { deploymentProjectPath }, _session);
var additionalReplacements = await GetReplacements();
@@ -199,7 +199,7 @@ public async Task CreateContainerDeploymentBundle(CloudApplication cloudAp
}
catch (DockerEngineExceptionBase ex)
{
- throw new FailedToGenerateDockerFileException("Failed to generate a docker file", ex);
+ throw new FailedToGenerateDockerFileException(DeployToolErrorCode.FailedToGenerateDockerFile, "Failed to generate a docker file", ex);
}
}
diff --git a/src/AWS.Deploy.Orchestration/RecipeHandler.cs b/src/AWS.Deploy.Orchestration/RecipeHandler.cs
index 27721f83b..785b925be 100644
--- a/src/AWS.Deploy.Orchestration/RecipeHandler.cs
+++ b/src/AWS.Deploy.Orchestration/RecipeHandler.cs
@@ -51,7 +51,7 @@ public static async Task> GetRecipeDefinitions(ICustomRec
}
catch(IOException)
{
- throw new NoRecipeDefinitionsFoundException("Failed to find recipe definitions");
+ throw new NoRecipeDefinitionsFoundException(DeployToolErrorCode.FailedToFindRecipeDefinitions, "Failed to find recipe definitions");
}
return recipeDefinitions;
diff --git a/src/AWS.Deploy.Orchestration/RecommendationEngine/RecommendationEngine.cs b/src/AWS.Deploy.Orchestration/RecommendationEngine/RecommendationEngine.cs
index 6d12b199c..4002c8bb4 100644
--- a/src/AWS.Deploy.Orchestration/RecommendationEngine/RecommendationEngine.cs
+++ b/src/AWS.Deploy.Orchestration/RecommendationEngine/RecommendationEngine.cs
@@ -101,10 +101,10 @@ public List GetDeploymentBundleSettings(DeploymentBundleTypes
}
catch(IOException)
{
- throw new NoDeploymentBundleDefinitionsFoundException("Failed to find a deployment bundle definition");
+ throw new NoDeploymentBundleDefinitionsFoundException(DeployToolErrorCode.DeploymentBundleDefinitionNotFound, "Failed to find a deployment bundle definition");
}
- throw new NoDeploymentBundleDefinitionsFoundException("Failed to find a deployment bundle definition");
+ throw new NoDeploymentBundleDefinitionsFoundException(DeployToolErrorCode.DeploymentBundleDefinitionNotFound, "Failed to find a deployment bundle definition");
}
public async Task EvaluateRules(IList rules)
@@ -125,7 +125,7 @@ public async Task EvaluateRules(IList rules
{
if(!availableTests.TryGetValue(test.Type, out var testInstance))
{
- throw new InvalidRecipeDefinitionException($"Invalid test type [{test.Type}] found in rule.");
+ throw new InvalidRecipeDefinitionException(DeployToolErrorCode.RuleHasInvalidTestType, $"Invalid test type [{test.Type}] found in rule.");
}
var input = new RecommendationTestInput(
diff --git a/src/AWS.Deploy.Orchestration/SystemCapabilityEvaluator.cs b/src/AWS.Deploy.Orchestration/SystemCapabilityEvaluator.cs
index e13baf533..390948099 100644
--- a/src/AWS.Deploy.Orchestration/SystemCapabilityEvaluator.cs
+++ b/src/AWS.Deploy.Orchestration/SystemCapabilityEvaluator.cs
@@ -50,7 +50,7 @@ await _commandLineWrapper.Run(
processExitCode = proc.ExitCode;
containerType = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ?
proc.StandardOut?.TrimEnd('\n') ??
- throw new DockerInfoException("Failed to check if Docker is running in Windows or Linux container mode.") :
+ throw new DockerInfoException(DeployToolErrorCode.FailedToCheckDockerInfo, "Failed to check if Docker is running in Windows or Linux container mode.") :
"linux";
});
diff --git a/src/AWS.Deploy.Orchestration/TemplateEngine.cs b/src/AWS.Deploy.Orchestration/TemplateEngine.cs
index 361737624..b27a1b5d5 100644
--- a/src/AWS.Deploy.Orchestration/TemplateEngine.cs
+++ b/src/AWS.Deploy.Orchestration/TemplateEngine.cs
@@ -46,7 +46,7 @@ public void GenerateCDKProjectFromTemplate(Recommendation recommendation, Orches
//The location of the base template that will be installed into the templating engine
var cdkProjectTemplateDirectory = Path.Combine(
Path.GetDirectoryName(recommendation.Recipe.RecipePath) ??
- throw new InvalidRecipePathException($"The following RecipePath is invalid as we could not retrieve the parent directory: {recommendation.Recipe.RecipePath}"),
+ throw new InvalidRecipePathException(DeployToolErrorCode.BaseTemplatesInvalidPath, $"The following RecipePath is invalid as we could not retrieve the parent directory: {recommendation.Recipe.RecipePath}"),
recommendation.Recipe.CdkProjectTemplate);
//Installing the base template into the templating engine to make it available for generation
@@ -69,7 +69,7 @@ public void GenerateCDKProjectFromTemplate(Recommendation recommendation, Orches
// CDK Template projects can parameterize the version number of the AWS.Deploy.Recipes.CDK.Common package. This avoid
// projects having to be modified every time the package version is bumped.
{ "AWSDeployRecipesCDKCommonVersion", FileVersionInfo.GetVersionInfo(typeof(Constants.CloudFormationIdentifier).Assembly.Location).ProductVersion
- ?? throw new InvalidAWSDeployRecipesCDKCommonVersionException("The version number of the AWS.Deploy.Recipes.CDK.Common package is invalid.") }
+ ?? throw new InvalidAWSDeployRecipesCDKCommonVersionException(DeployToolErrorCode.InvalidAWSDeployRecipesCDKCommonVersion, "The version number of the AWS.Deploy.Recipes.CDK.Common package is invalid.") }
};
try
@@ -82,7 +82,7 @@ public void GenerateCDKProjectFromTemplate(Recommendation recommendation, Orches
}
catch
{
- throw new TemplateGenerationFailedException("Failed to generate CDK project from template");
+ throw new TemplateGenerationFailedException(DeployToolErrorCode.FailedToGenerateCDKProjectFromTemplate, "Failed to generate CDK project from template");
}
}
@@ -97,7 +97,7 @@ private void InstallTemplates(string folderLocation)
}
catch(Exception e)
{
- throw new DefaultTemplateInstallationFailedException("Failed to install the default template that is required to the generate the CDK project", e);
+ throw new DefaultTemplateInstallationFailedException(DeployToolErrorCode.FailedToInstallProjectTemplates, "Failed to install the default template that is required to the generate the CDK project", e);
}
}
diff --git a/src/AWS.Deploy.Orchestration/Utilities/TemplateMetadataReader.cs b/src/AWS.Deploy.Orchestration/Utilities/TemplateMetadataReader.cs
index d9a87cff0..08dc4035b 100644
--- a/src/AWS.Deploy.Orchestration/Utilities/TemplateMetadataReader.cs
+++ b/src/AWS.Deploy.Orchestration/Utilities/TemplateMetadataReader.cs
@@ -78,7 +78,7 @@ private static CloudApplicationMetadata ReadSettings(string templateBody)
}
catch(Exception e)
{
- throw new ParsingExistingCloudApplicationMetadataException("Error parsing existing application's metadata", e);
+ throw new ParsingExistingCloudApplicationMetadataException(DeployToolErrorCode.ErrorParsingApplicationMetadata, "Error parsing existing application's metadata", e);
}
}
diff --git a/src/AWS.Deploy.Orchestration/Utilities/ZipFileManager.cs b/src/AWS.Deploy.Orchestration/Utilities/ZipFileManager.cs
index 79ec963e6..3c945109e 100644
--- a/src/AWS.Deploy.Orchestration/Utilities/ZipFileManager.cs
+++ b/src/AWS.Deploy.Orchestration/Utilities/ZipFileManager.cs
@@ -8,6 +8,7 @@
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
+using AWS.Deploy.Common;
using AWS.Deploy.Common.IO;
namespace AWS.Deploy.Orchestration.Utilities
@@ -48,7 +49,7 @@ private async Task BuildZipForLinux(string sourceDirectoryName, string destinati
var zipCLI = FindExecutableInPath("zip");
if (string.IsNullOrEmpty(zipCLI))
- throw new FailedToCreateZipFileException("Failed to find the \"zip\" utility program in path. This program is required to maintain Linux file permissions in the zip archive.");
+ throw new FailedToCreateZipFileException(DeployToolErrorCode.FailedToFindZipUtility, "Failed to find the \"zip\" utility program in path. This program is required to maintain Linux file permissions in the zip archive.");
var args = new StringBuilder($"\"{destinationArchiveFileName}\"");
@@ -61,7 +62,7 @@ private async Task BuildZipForLinux(string sourceDirectoryName, string destinati
var command = $"{zipCLI} {args}";
var result = await _commandLineWrapper.TryRunWithResult(command, sourceDirectoryName);
if (result.ExitCode != 0)
- throw new FailedToCreateZipFileException("\"zip\" utility program has failed to create a zip archive.");
+ throw new FailedToCreateZipFileException(DeployToolErrorCode.ZipUtilityFailedToZip, "\"zip\" utility program has failed to create a zip archive.");
}
///
diff --git a/src/AWS.Deploy.ServerMode.Client/RestAPI.cs b/src/AWS.Deploy.ServerMode.Client/RestAPI.cs
index 1bb2eb449..1be411a07 100644
--- a/src/AWS.Deploy.ServerMode.Client/RestAPI.cs
+++ b/src/AWS.Deploy.ServerMode.Client/RestAPI.cs
@@ -1476,6 +1476,18 @@ public enum DeploymentStatus
}
+ [System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.4.1.0 (Newtonsoft.Json v12.0.0.0)")]
+ public partial class DeployToolExceptionSummary
+ {
+ [Newtonsoft.Json.JsonProperty("errorCode", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string ErrorCode { get; set; }
+
+ [Newtonsoft.Json.JsonProperty("message", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public string Message { get; set; }
+
+
+ }
+
[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.4.1.0 (Newtonsoft.Json v12.0.0.0)")]
public partial class DisplayedResourceSummary
{
@@ -1567,6 +1579,9 @@ public partial class GetDeploymentStatusOutput
[Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
public DeploymentStatus Status { get; set; }
+ [Newtonsoft.Json.JsonProperty("exception", Required = Newtonsoft.Json.Required.Default, NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
+ public DeployToolExceptionSummary Exception { get; set; }
+
}
diff --git a/version.json b/version.json
index 710f7f584..2848fe8f8 100644
--- a/version.json
+++ b/version.json
@@ -1,6 +1,6 @@
{
"$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
- "version": "0.29",
+ "version": "0.30",
"publicReleaseRefSpec": [
".*"
],