Skip to content

Commit

Permalink
chore: migrate env to new error handling (#11053)
Browse files Browse the repository at this point in the history
* chore: migrate env to new error handling

* chore: update to use troubleshooting link shorthand method

* chore: throw amplify error on BackendDeleteFault

* chore: update pr to use troubleshooting link instead

* chore: fix unused import

* chore: moved error message to details section

* fix: updated test to expect correct error type
  • Loading branch information
awsluja authored Sep 29, 2022
1 parent 0c745c4 commit e4593c4
Show file tree
Hide file tree
Showing 11 changed files with 214 additions and 162 deletions.
3 changes: 3 additions & 0 deletions packages/amplify-cli-core/src/errors/amplify-exception.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export type AmplifyErrorType =
| 'DirectoryError'
| 'DirectoryAlreadyExistsError'
| 'DuplicateLogicalIdError'
| 'EnvironmentConfigurationError'
| 'EnvironmentNameError'
| 'EnvironmentNotInitializedError'
| 'FeatureFlagsValidationError'
Expand Down Expand Up @@ -121,10 +122,12 @@ export type AmplifyErrorType =
export type AmplifyFaultType =
| 'AmplifyBackupFault'
| 'BackendPullFault'
| 'BackendDeleteFault'
| 'DeploymentFault'
| 'NotImplementedFault'
| 'ProjectDeleteFault'
| 'ProjectInitFault'
| 'PluginNotLoadedFault'
| 'PushResourcesFault'
| 'PullBackendFault'
| 'ResourceExportFault'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ jest.mock('../../../extensions/amplify-helpers/get-project-config', () => ({
}),
}));

// eslint-disable-next-line spellcheck/spell-checker
jest.mock('../../../extensions/amplify-helpers/get-all-category-pluginInfos', () => ({
getAllCategoryPluginInfo: jest.fn().mockReturnValue({}),
}));
Expand Down Expand Up @@ -35,12 +36,13 @@ const context = {
error: jest.fn(),
},
};
const envName = 'test';

describe('remove-env-from-cloud', () => {
it('invoke deleteEnv method in provider plugin', async () => {
await removeEnvFromCloud(context, 'test', false);
await removeEnvFromCloud(context, envName, false);

expect(deleteEnvMock).toBeCalledWith(context, 'test', false);
expect(deleteEnvMock).toBeCalledWith(context, envName, false);
});

it('invoke deletePinpointAppForEnv method in notificationsModule', async () => {
Expand All @@ -52,22 +54,24 @@ describe('remove-env-from-cloud', () => {
],
});

await removeEnvFromCloud(context, 'test', false);
await removeEnvFromCloud(context, envName, false);

expect(deletePinpointAppForEnvMock).toBeCalledWith(context, 'test');
expect(deletePinpointAppForEnvMock).toBeCalledWith(context, envName);
});

it('throws error when deleteEnv promise rejected', async () => {
deleteEnvMock.mockRejectedValue(new Error('deleteEnv error'));
deleteEnvMock.mockRejectedValue(new Error('a generic deleteEnv error'));

await expect(removeEnvFromCloud(context, 'test', false)).rejects.toThrow('deleteEnv error');
await expect(removeEnvFromCloud(context, envName, false))
.rejects
.toThrow(`Error occurred while deleting env: ${envName}.`);
});

it('does not throw not found error when deleteEnv promise rejected', async () => {
const e: any = new Error('deleteEnv error');
e.code = 'NotFoundException';
deleteEnvMock.mockRejectedValue(e);

await expect(removeEnvFromCloud(context, 'test', false)).resolves.not.toThrow('deleteEnv error');
await expect(removeEnvFromCloud(context, envName, false)).resolves.not.toThrow(`Error occurred while deleting env: ${envName}.`);
});
});
17 changes: 11 additions & 6 deletions packages/amplify-cli/src/commands/env/add.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import { $TSContext, pathManager } from 'amplify-cli-core';
import { run as init } from '../init';
import { $TSContext, pathManager, AmplifyError } from 'amplify-cli-core';
import fs from 'fs-extra';
import { run as init } from '../init';

export const run = async (context: $TSContext) => {
/**
* Executes the 'env add' command
*/
export const run = async (context: $TSContext) : Promise<void> => {
const amplifyMetaFilePath = pathManager.getAmplifyMetaFilePath();
if (!fs.existsSync(amplifyMetaFilePath)) {
throw new Error(
'Your workspace is not configured to modify the backend. If you wish to change this configuration, remove your `amplify` directory and pull the project again.',
);
throw new AmplifyError('ConfigurationError', {
// eslint-disable-next-line spellcheck/spell-checker
message: 'Your workspace is not configured to modify the backend.',
resolution: 'If you wish to change this configuration, remove your `amplify` directory and pull the project again.',
});
}
await init(context);
};
49 changes: 21 additions & 28 deletions packages/amplify-cli/src/commands/env/get.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,33 @@
import chalk from 'chalk';
import { JSONUtilities, $TSContext, UnknownArgumentError, exitOnNextTick } from 'amplify-cli-core';
import { JSONUtilities, $TSContext, AmplifyError } from 'amplify-cli-core';
import { printer } from 'amplify-prompts';
import { printEnvInfo } from '../helpers/envUtils';

export const run = async (context: $TSContext) => {
/**
* Executes the 'env get' command
*/
export const run = async (context: $TSContext) : Promise<void> => {
const envName = context.parameters.options.name;
const allEnvs = context.amplify.getEnvDetails();

if (!envName) {
const errMessage = 'You must pass in the name of the environment using the --name flag';
context.print.error(errMessage);
context.usageData.emitError(new UnknownArgumentError(errMessage));
exitOnNextTick(1);
throw new AmplifyError('EnvironmentNameError', {
message: 'Environment name was not specified.',
resolution: 'Pass in the name of the environment using the --name flag.',
});
}
if (!allEnvs[envName]) {
throw new AmplifyError('EnvironmentNameError', {
message: 'Environment name is invalid.',
resolution: 'Run amplify env list to get a list of valid environments.',
});
}

const allEnvs = context.amplify.getEnvDetails();

if (context.parameters.options.json) {
if (allEnvs[envName]) {
context.print.fancy(JSONUtilities.stringify(allEnvs[envName]));
} else {
context.print.fancy(JSONUtilities.stringify({ error: `No environment found with name: '${envName}'` }));
}
printer.info(JSONUtilities.stringify(allEnvs[envName]) as string);
return;
}

let envFound = false;

Object.keys(allEnvs).forEach(env => {
if (env === envName) {
envFound = true;
context.print.info('');
context.print.info(chalk.red(env));
printEnvInfo(context, env, allEnvs);
}
});

if (!envFound) {
context.print.error('No environment found with the corresponding name provided');
}
printer.blankLine();
printer.info(envName, 'red');
printEnvInfo(envName, allEnvs);
};
36 changes: 21 additions & 15 deletions packages/amplify-cli/src/commands/env/import.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import {
$TSContext, JSONUtilities, stateManager, UnknownArgumentError, exitOnNextTick,
$TSContext, JSONUtilities, stateManager, AmplifyError,
} from 'amplify-cli-core';
import { printer } from 'amplify-prompts';

/**
* Entry point for import command
*/
export const run = async (context: $TSContext): Promise<void> => {
const envName = context.parameters.options.name;
if (!envName) {
const errMessage = 'You must pass in the name of the environment using the --name flag';
context.print.error(errMessage);
context.usageData.emitError(new UnknownArgumentError(errMessage));
exitOnNextTick(1);
throw new AmplifyError('EnvironmentNameError', {
message: 'Environment name was not specified.',
resolution: 'Pass in the name of the environment using the --name flag.',
});
}

let config;
Expand Down Expand Up @@ -46,13 +47,17 @@ export const run = async (context: $TSContext): Promise<void> => {
/* eslint-enable no-prototype-builtins */
)
) {
throw new Error('The provided config was invalid or incomplete');
throw new AmplifyError('EnvironmentConfigurationError', {
message: 'The environment configuration provided is missing required properties.',
resolution: 'Add the required properties and try again.',
link: 'https://docs.amplify.aws/cli/teams/commands/#import-an-environment',
});
}
} catch (e) {
const errMessage = 'You must pass in the configs of the environment in an object format using the --config flag';
context.print.error(errMessage);
context.usageData.emitError(new UnknownArgumentError(errMessage));
exitOnNextTick(1);
throw new AmplifyError('EnvironmentConfigurationError', {
message: 'Environment configuration was not specified or was formatted incorrectly.',
resolution: 'You must pass in the configuration of the environment in an object format using the --config flag.',
});
}

let awsInfo;
Expand All @@ -61,10 +66,11 @@ export const run = async (context: $TSContext): Promise<void> => {
try {
awsInfo = JSONUtilities.parse(context.parameters.options.awsInfo);
} catch (e) {
const errMessage = 'You must pass in the AWS credential info in an object format for initializing your environment using the --awsInfo flag';
context.print.error(errMessage);
context.usageData.emitError(new UnknownArgumentError(errMessage));
exitOnNextTick(1);
throw new AmplifyError('EnvironmentConfigurationError', {
message: 'The AWS credential info was not specified or was incorrectly formatted.',
resolution: 'Pass in the AWS credential info in an object format using the --awsInfo flag.',
link: 'https://docs.amplify.aws/cli/teams/commands/#import-an-environment',
});
}
}

Expand All @@ -83,7 +89,7 @@ export const run = async (context: $TSContext): Promise<void> => {

stateManager.setLocalAWSInfo(undefined, envAwsInfo);

context.print.success('Successfully added environment from your project');
printer.success('Successfully added environment from your project');
};

// eslint-disable-next-line spellcheck/spell-checker
Expand Down
23 changes: 13 additions & 10 deletions packages/amplify-cli/src/commands/env/list.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,32 @@
import chalk from 'chalk';
import { JSONUtilities } from 'amplify-cli-core';
import { printer } from 'amplify-prompts';
import { printEnvInfo } from '../helpers/envUtils';

export const run = async context => {
/**
* Executes the 'env list' command
*/
export const run = async (context): Promise<void> => {
const { envName } = context.amplify.getEnvInfo();

if (context.parameters.options.details) {
const allEnvs = context.amplify.getEnvDetails();
if (context.parameters.options.json) {
context.print.fancy(JSONUtilities.stringify(allEnvs));
printer.info(JSONUtilities.stringify(allEnvs) as string);
return;
}
Object.keys(allEnvs).forEach(env => {
context.print.info('');
printer.blankLine();
if (envName === env) {
context.print.info(chalk.red(`*${env}*`));
printer.info(`*${env}*`, 'red');
} else {
context.print.info(chalk.yellow(env));
printer.info(env, 'yellow');
}
printEnvInfo(context, env, allEnvs);
printEnvInfo(env, allEnvs);
});
} else {
const allEnvs = context.amplify.getAllEnvs();
if (context.parameters.options.json) {
context.print.fancy(JSONUtilities.stringify({ envs: allEnvs }));
printer.info(JSONUtilities.stringify({ envs: allEnvs }) as string);
return;
}
const { table } = context.print;
Expand All @@ -35,8 +38,8 @@ export const run = async context => {
tableOptions.push([allEnvs[i]]);
}
}
context.print.info('');
printer.blankLine();
table(tableOptions, { format: 'markdown' });
context.print.info('');
printer.blankLine();
}
};
Loading

0 comments on commit e4593c4

Please sign in to comment.