Skip to content

Commit

Permalink
chore(cli): improve error message for cdk migrate (#29392)
Browse files Browse the repository at this point in the history
### Reason for this change

This change is a follow-up to a [PR](cdklabs/cdk-from-cfn#594) that improved the error message thrown by `cdk-from-cfn` when an invalid resource property was used in a CloudFormation template. This PR further improves the error message on the cli side.

### Description of changes

Primarily, this PR is a verbiage change. The base error message now states that the `<stack-name> could not be generated because <error-message>`. The error message itself is checked against `unreachable` because any use of `panic!`, `unreachable!`, or `unimplemented!` will cause the `cdk-from-cfn` source code to panic in-place. In the resulting wasm binary, this produces a `RuntimeError` that has an error message of `unreachable`. I've improved this slightly by stating `template and/or language inputs caused the source code to panic`. If the error message is not `unreachable`, then the error message is taken as is with `TransmuteError:` replaced.

Note that we should still continue to improve our error messages in `cdk-from-cfn` by by replacing `panic!`, `unreachable!`, and `unimplemented!` with more detailed error messages.

### Description of how you validated changes

An existing unit test was changed based on the error message verbiage change. Additionally, a new unit test was added to validate that the expected error message would be thrown by the cli when an invalid resource property was used in a CloudFormation template.

### Checklist
- [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md)

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
colifran committed Mar 8, 2024
1 parent 1f8acc1 commit 110c79f
Show file tree
Hide file tree
Showing 8 changed files with 39 additions and 12 deletions.
2 changes: 1 addition & 1 deletion packages/@aws-cdk/cli-lib-alpha/THIRD_PARTY_LICENSES
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI

----------------

** cdk-from-cfn@0.133.0 - https://www.npmjs.com/package/cdk-from-cfn/v/0.133.0 | MIT OR Apache-2.0
** cdk-from-cfn@0.141.0 - https://www.npmjs.com/package/cdk-from-cfn/v/0.141.0 | MIT OR Apache-2.0

----------------

Expand Down
2 changes: 1 addition & 1 deletion packages/aws-cdk/THIRD_PARTY_LICENSES
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI

----------------

** cdk-from-cfn@0.133.0 - https://www.npmjs.com/package/cdk-from-cfn/v/0.133.0 | MIT OR Apache-2.0
** cdk-from-cfn@0.141.0 - https://www.npmjs.com/package/cdk-from-cfn/v/0.141.0 | MIT OR Apache-2.0

----------------

Expand Down
7 changes: 5 additions & 2 deletions packages/aws-cdk/lib/commands/migrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,14 @@ export async function generateCdkApp(stackName: string, stack: string, language:
* @returns A string representation of a CDK stack file
*/
export function generateStack(template: string, stackName: string, language: string) {
const formattedStackName = `${camelCase(decamelize(stackName), { pascalCase: true })}Stack`;
try {
const formattedStackName = `${camelCase(decamelize(stackName), { pascalCase: true })}Stack`;
return cdk_from_cfn.transmute(template, language, formattedStackName);
} catch (e) {
throw new Error(`stack generation failed due to error '${(e as Error).message}'`);
const errorMessage = (e as Error).message === 'unreachable'
? 'template and/or language inputs caused the source code to panic'
: (e as Error).message.replace('TransmuteError: ', '');
throw new Error(`${formattedStackName} could not be generated because ${errorMessage}`);
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/aws-cdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@
"aws-sdk": "^2.1562.0",
"camelcase": "^6.3.0",
"cdk-assets": "0.0.0",
"cdk-from-cfn": "^0.133.0",
"cdk-from-cfn": "^0.141.0",
"chalk": "^4",
"chokidar": "^3.6.0",
"decamelize": "^5.0.1",
Expand Down
4 changes: 2 additions & 2 deletions packages/aws-cdk/test/cdk-toolkit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -918,8 +918,8 @@ describe('synth', () => {
stackName: 'cannot-generate-template',
fromPath: path.join(__dirname, 'commands', 'test-resources', 'templates', 'sqs-template.json'),
language: 'rust',
})).rejects.toThrowError('stack generation failed due to error \'unreachable\'');
expect(stderrMock.mock.calls[1][0]).toContain(' ❌ Migrate failed for `cannot-generate-template`: stack generation failed due to error \'unreachable\'');
})).rejects.toThrowError('CannotGenerateTemplateStack could not be generated because template and/or language inputs caused the source code to panic');
expect(stderrMock.mock.calls[1][0]).toContain(' ❌ Migrate failed for `cannot-generate-template`: CannotGenerateTemplateStack could not be generated because template and/or language inputs caused the source code to panic');
});

cliTest('migrate succeeds for valid template from local path when no lanugage is provided', async (workDir) => {
Expand Down
8 changes: 7 additions & 1 deletion packages/aws-cdk/test/commands/migrate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ describe('Migrate Function Tests', () => {

const validTemplatePath = path.join(...templatePath, 's3-template.json');
const emptyTemplatePath = path.join(...templatePath, 'empty-template.yml');
const invalidTemplatePath = path.join(...templatePath, 'rds-template.json');
const validTemplate = readFromPath(validTemplatePath)!;
const invalidTemplate = readFromPath(invalidTemplatePath)!;

beforeEach(async () => {
sdkProvider = new MockSdkProvider();
Expand Down Expand Up @@ -132,7 +134,11 @@ describe('Migrate Function Tests', () => {
});

test('generateStack throws error when called for other language', () => {
expect(() => generateStack(validTemplate, 'BadBadBad', 'php')).toThrowError('stack generation failed due to error \'unreachable\'');
expect(() => generateStack(validTemplate, 'BadBadBad', 'php')).toThrowError('BadBadBadStack could not be generated because template and/or language inputs caused the source code to panic');
});

test('generateStack throws error for invalid resource property', () => {
expect(() => generateStack(invalidTemplate, 'VeryBad', 'typescript')).toThrow('VeryBadStack could not be generated because ReadEndpoint is not a valid property for resource RDSCluster of type AWS::RDS::DBCluster');
});

cliTest('generateCdkApp generates the expected cdk app when called for typescript', async (workDir) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"AWSTemplateFormatVersion": "2010-09-09",
"Resources": {
"RDSCluster": {
"Type": "AWS::RDS::DBCluster",
"Properties": {
"DBClusterIdentifier" : "aurora-postgresql-cluster",
"Engine" : "aurora-postgresql",
"EngineVersion" : "10.7",
"DBClusterParameterGroupName" : "default.aurora-postgresql10",
"EnableCloudwatchLogsExports" : ["postgresql"],
"ReadEndpoint": {
"Address": "http://127.0.0.1:8080"
}
}
}
}
}
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -6307,10 +6307,10 @@ case@1.6.3, case@^1.6.3:
resolved "https://registry.npmjs.org/case/-/case-1.6.3.tgz#0a4386e3e9825351ca2e6216c60467ff5f1ea1c9"
integrity sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ==

cdk-from-cfn@^0.133.0:
version "0.133.0"
resolved "https://registry.npmjs.org/cdk-from-cfn/-/cdk-from-cfn-0.133.0.tgz#a18dd2c505c8fc0b7f4947f6d6afb3e7fea5b391"
integrity sha512-Yj0kE+GixlSGLNTodCaZEcIeyxzNQonZAykmsSP7wRSm3yYNfg/2XX1tRWi9hzUGMwqYuQr5GsCBymukU0GKsA==
cdk-from-cfn@^0.141.0:
version "0.141.0"
resolved "https://registry.npmjs.org/cdk-from-cfn/-/cdk-from-cfn-0.141.0.tgz#f480ee87658f8056a933e4684198b050cb783e8f"
integrity sha512-saEHn8rxR3a2b0MpOAjnNMeLOoCKo9lSKYMm7GsAPlzyMOiTmTQeIwKhUAgt8ouVbt4VZPddBukzmfh5+xtCYw==

cdk-generate-synthetic-examples@^0.1.304:
version "0.1.304"
Expand Down

0 comments on commit 110c79f

Please sign in to comment.