From 110c79ff5b1a8a47d9bedc8df331a98d0431f915 Mon Sep 17 00:00:00 2001 From: Colin Francis <131073567+colifran@users.noreply.github.com> Date: Fri, 8 Mar 2024 11:27:53 -0500 Subject: [PATCH] chore(cli): improve error message for cdk migrate (#29392) ### Reason for this change This change is a follow-up to a [PR](https://github.com/cdklabs/cdk-from-cfn/pull/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 ` could not be generated because `. 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* --- .../cli-lib-alpha/THIRD_PARTY_LICENSES | 2 +- packages/aws-cdk/THIRD_PARTY_LICENSES | 2 +- packages/aws-cdk/lib/commands/migrate.ts | 7 +++++-- packages/aws-cdk/package.json | 2 +- packages/aws-cdk/test/cdk-toolkit.test.ts | 4 ++-- packages/aws-cdk/test/commands/migrate.test.ts | 8 +++++++- .../test-resources/templates/rds-template.json | 18 ++++++++++++++++++ yarn.lock | 8 ++++---- 8 files changed, 39 insertions(+), 12 deletions(-) create mode 100644 packages/aws-cdk/test/commands/test-resources/templates/rds-template.json diff --git a/packages/@aws-cdk/cli-lib-alpha/THIRD_PARTY_LICENSES b/packages/@aws-cdk/cli-lib-alpha/THIRD_PARTY_LICENSES index 1c24888d7bb02..87594dfec653c 100644 --- a/packages/@aws-cdk/cli-lib-alpha/THIRD_PARTY_LICENSES +++ b/packages/@aws-cdk/cli-lib-alpha/THIRD_PARTY_LICENSES @@ -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 ---------------- diff --git a/packages/aws-cdk/THIRD_PARTY_LICENSES b/packages/aws-cdk/THIRD_PARTY_LICENSES index c947720e91891..a8bdfa43f5001 100644 --- a/packages/aws-cdk/THIRD_PARTY_LICENSES +++ b/packages/aws-cdk/THIRD_PARTY_LICENSES @@ -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 ---------------- diff --git a/packages/aws-cdk/lib/commands/migrate.ts b/packages/aws-cdk/lib/commands/migrate.ts index 1703a60392848..8a3b462877755 100644 --- a/packages/aws-cdk/lib/commands/migrate.ts +++ b/packages/aws-cdk/lib/commands/migrate.ts @@ -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}`); } } diff --git a/packages/aws-cdk/package.json b/packages/aws-cdk/package.json index 9778f4452c8e0..fa51f646e6918 100644 --- a/packages/aws-cdk/package.json +++ b/packages/aws-cdk/package.json @@ -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", diff --git a/packages/aws-cdk/test/cdk-toolkit.test.ts b/packages/aws-cdk/test/cdk-toolkit.test.ts index 1a6f55ef63c52..7b17498d4087a 100644 --- a/packages/aws-cdk/test/cdk-toolkit.test.ts +++ b/packages/aws-cdk/test/cdk-toolkit.test.ts @@ -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) => { diff --git a/packages/aws-cdk/test/commands/migrate.test.ts b/packages/aws-cdk/test/commands/migrate.test.ts index ed0cef6bd1b70..86dcce27f25bf 100644 --- a/packages/aws-cdk/test/commands/migrate.test.ts +++ b/packages/aws-cdk/test/commands/migrate.test.ts @@ -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(); @@ -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) => { diff --git a/packages/aws-cdk/test/commands/test-resources/templates/rds-template.json b/packages/aws-cdk/test/commands/test-resources/templates/rds-template.json new file mode 100644 index 0000000000000..9348b1b7a9e84 --- /dev/null +++ b/packages/aws-cdk/test/commands/test-resources/templates/rds-template.json @@ -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" + } + } + } + } +} diff --git a/yarn.lock b/yarn.lock index 2cbafb6831dea..fd141c7631a27 100644 --- a/yarn.lock +++ b/yarn.lock @@ -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"