diff --git a/packages/core/src/awsService/appBuilder/explorer/detectSamProjects.ts b/packages/core/src/awsService/appBuilder/explorer/detectSamProjects.ts index f17bec9213a..511217481b3 100644 --- a/packages/core/src/awsService/appBuilder/explorer/detectSamProjects.ts +++ b/packages/core/src/awsService/appBuilder/explorer/detectSamProjects.ts @@ -57,7 +57,7 @@ export async function getFiles( return await vscode.workspace.findFiles(globPattern, excludePattern) } catch (error) { - getLogger().error(`Failed to get files with pattern ${pattern}:`, error) + getLogger().error(`Failed to find files with pattern ${pattern}:`, error) return [] } } diff --git a/packages/core/src/awsService/appBuilder/explorer/nodes/appNode.ts b/packages/core/src/awsService/appBuilder/explorer/nodes/appNode.ts index 5f8c6b4a81e..d7d5e51bb51 100644 --- a/packages/core/src/awsService/appBuilder/explorer/nodes/appNode.ts +++ b/packages/core/src/awsService/appBuilder/explorer/nodes/appNode.ts @@ -73,7 +73,7 @@ export class AppNode implements TreeNode { createPlaceholderItem( localize( 'AWS.appBuilder.explorerNode.app.noResourceTree', - '[Unable to load Resource tree for this App. Update SAM template]' + '[Unable to load resource tree for this app. Ensure SAM template is correct.]' ) ), ] diff --git a/packages/core/src/awsService/appBuilder/explorer/nodes/deployedNode.ts b/packages/core/src/awsService/appBuilder/explorer/nodes/deployedNode.ts index 913cdd067e0..cb0d1a669c8 100644 --- a/packages/core/src/awsService/appBuilder/explorer/nodes/deployedNode.ts +++ b/packages/core/src/awsService/appBuilder/explorer/nodes/deployedNode.ts @@ -96,7 +96,7 @@ export async function generateDeployedNode( .Configuration as Lambda.FunctionConfiguration newDeployedResource = new LambdaFunctionNode(lambdaNode, regionCode, configuration) } catch (error: any) { - getLogger().error('Error getting Lambda configuration %O', error) + getLogger().error('Error getting Lambda configuration: %O', error) throw ToolkitError.chain(error, 'Error getting Lambda configuration', { code: 'lambdaClientError', }) @@ -107,7 +107,7 @@ export async function generateDeployedNode( createPlaceholderItem( localize( 'AWS.appBuilder.explorerNode.unavailableDeployedResource', - '[Failed to retrive deployed resource.]' + '[Failed to retrive deployed resource. Ensure your AWS account is connected.]' ) ), ] @@ -119,8 +119,8 @@ export async function generateDeployedNode( try { v3configuration = (await v3Client.send(v3command)).Configuration as FunctionConfiguration logGroupName = v3configuration.LoggingConfig?.LogGroup - } catch { - getLogger().error('Error getting Lambda V3 configuration') + } catch (error: any) { + getLogger().error('Error getting Lambda V3 configuration: %O', error) } newDeployedResource.configuration = { ...newDeployedResource.configuration, @@ -156,7 +156,10 @@ export async function generateDeployedNode( getLogger().info('Details are missing or are incomplete for: %O', deployedResource) return [ createPlaceholderItem( - localize('AWS.appBuilder.explorerNode.noApps', '[This resource is not yet supported.]') + localize( + 'AWS.appBuilder.explorerNode.noApps', + '[This resource is not yet supported in AppBuilder.]' + ) ), ] } @@ -166,7 +169,7 @@ export async function generateDeployedNode( createPlaceholderItem( localize( 'AWS.appBuilder.explorerNode.unavailableDeployedResource', - '[Failed to retrive deployed resource.]' + '[Failed to retrieve deployed resource. Ensure correct stack name and region are in the samconfig.toml, and that your account is connected.]' ) ), ] diff --git a/packages/core/src/awsService/appBuilder/explorer/samProject.ts b/packages/core/src/awsService/appBuilder/explorer/samProject.ts index fd571cd6be8..ce8d0c4878a 100644 --- a/packages/core/src/awsService/appBuilder/explorer/samProject.ts +++ b/packages/core/src/awsService/appBuilder/explorer/samProject.ts @@ -42,14 +42,17 @@ export async function getStackName(projectRoot: vscode.Uri): Promise { } catch (error: any) { switch (error.code) { case SamConfigErrorCode.samNoConfigFound: - getLogger().info('No stack name or region information available in samconfig.toml: %O', error) + getLogger().info('Stack name and/or region information not found in samconfig.toml: %O', error) break case SamConfigErrorCode.samConfigParseError: - getLogger().error(`Error getting stack name or region information: ${error.message}`, error) + getLogger().error( + `Error parsing stack name and/or region information from samconfig.toml: ${error.message}. Ensure the information is correct.`, + error + ) void showViewLogsMessage('Encountered an issue reading samconfig.toml') break default: - getLogger().warn(`Error getting stack name or region information: ${error.message}`, error) + getLogger().warn(`Error parsing stack name and/or region information: ${error.message}`, error) } return {} } diff --git a/packages/core/src/awsService/appBuilder/utils.ts b/packages/core/src/awsService/appBuilder/utils.ts index de3dee8770d..63b116b20eb 100644 --- a/packages/core/src/awsService/appBuilder/utils.ts +++ b/packages/core/src/awsService/appBuilder/utils.ts @@ -24,14 +24,14 @@ const localize = nls.loadMessageBundle() export async function runOpenTemplate(arg?: TreeNode) { const templateUri = arg ? (arg.resource as SamAppLocation).samTemplateUri : await promptUserForTemplate() if (!templateUri || !(await fs.exists(templateUri))) { - throw new ToolkitError('No template provided', { code: 'NoTemplateProvided' }) + throw new ToolkitError('SAM Template not found, cannot open template', { code: 'NoTemplateProvided' }) } const document = await vscode.workspace.openTextDocument(templateUri) await vscode.window.showTextDocument(document) } /** - * Find and open the lambda handler with given ResoruceNode + * Find and open the lambda handler with given ResourceNode * If not found, a NoHandlerFound error will be raised * @param arg ResourceNode */ @@ -56,9 +56,12 @@ export async function runOpenHandler(arg: ResourceNode): Promise { arg.resource.resource.Runtime ) if (!handlerFile) { - throw new ToolkitError(`No handler file found with name "${arg.resource.resource.Handler}"`, { - code: 'NoHandlerFound', - }) + throw new ToolkitError( + `No handler file found with name "${arg.resource.resource.Handler}". Ensure the file exists in the expected location."`, + { + code: 'NoHandlerFound', + } + ) } await vscode.workspace.openTextDocument(handlerFile).then(async (doc) => await vscode.window.showTextDocument(doc)) } @@ -90,7 +93,7 @@ export async function getLambdaHandlerFile( ): Promise { const family = getFamily(runtime) if (!supportedRuntimeForHandler.has(family)) { - throw new ToolkitError(`Runtime ${runtime} is not supported for open handler button`, { + throw new ToolkitError(`Runtime ${runtime} is not supported for the 'Open handler' button`, { code: 'RuntimeNotSupported', }) } diff --git a/packages/core/src/awsService/appBuilder/walkthrough.ts b/packages/core/src/awsService/appBuilder/walkthrough.ts index 04f43d61878..26760d896aa 100644 --- a/packages/core/src/awsService/appBuilder/walkthrough.ts +++ b/packages/core/src/awsService/appBuilder/walkthrough.ts @@ -148,13 +148,13 @@ export async function getTutorial( const appSelected = appMap.get(project + runtime) telemetry.record({ action: project + runtime, source: source ?? 'AppBuilderWalkthrough' }) if (!appSelected) { - throw new ToolkitError(`Tried to get template '${project}+${runtime}', but it hasn't been registered.`) + throw new ToolkitError(`Template '${project}+${runtime}' does not exist, choose another template.`) } try { await getPattern(serverlessLandOwner, serverlessLandRepo, appSelected.asset, outputDir, true) } catch (error) { - throw new ToolkitError(`Error occurred while fetching the pattern from serverlessland: ${error}`) + throw new ToolkitError(`An error occurred while fetching this pattern from Serverless Land: ${error}`) } } @@ -190,7 +190,7 @@ export async function genWalkthroughProject( 'No' ) if (choice !== 'Yes') { - throw new ToolkitError(`${defaultTemplateName} already exist`) + throw new ToolkitError(`A file named ${defaultTemplateName} already exists in this path.`) } } @@ -256,9 +256,9 @@ export async function initWalkthroughProjectCommand() { let runtimeSelected: TutorialRuntimeOptions | undefined = undefined try { if (!walkthroughSelected || !(typeof walkthroughSelected === 'string')) { - getLogger().info('exit on no walkthrough selected') + getLogger().info('No walkthrough selected - exiting') void vscode.window.showErrorMessage( - localize('AWS.toolkit.lambda.walkthroughNotSelected', 'Please select a template first') + localize('AWS.toolkit.lambda.walkthroughNotSelected', 'Select a template in the walkthrough.') ) return } @@ -322,7 +322,7 @@ export async function getOrUpdateOrInstallSAMCli(source: string) { } } } catch (err) { - throw ToolkitError.chain(err, 'Failed to install or detect SAM') + throw ToolkitError.chain(err, 'Failed to install or detect SAM.') } finally { telemetry.record({ source: source, toolId: 'sam-cli' }) } diff --git a/packages/core/src/test/awsService/appBuilder/explorer/detectSamProjects.test.ts b/packages/core/src/test/awsService/appBuilder/explorer/detectSamProjects.test.ts index b675b2452f8..74fafc20843 100644 --- a/packages/core/src/test/awsService/appBuilder/explorer/detectSamProjects.test.ts +++ b/packages/core/src/test/awsService/appBuilder/explorer/detectSamProjects.test.ts @@ -83,7 +83,7 @@ describe('getFiles', () => { const templateFiles = await getFiles(workspaceFolder, '**/template.{yml,yaml}', '**/.aws-sam/**') assert.strictEqual(templateFiles.length, 0) - assertLogsContain('Failed to get files with pattern', false, 'error') + assertLogsContain('Failed to find files with pattern', false, 'error') sandbox.restore() }) }) diff --git a/packages/core/src/test/awsService/appBuilder/explorer/samProject.test.ts b/packages/core/src/test/awsService/appBuilder/explorer/samProject.test.ts index de7a82e126a..f959ef0e572 100644 --- a/packages/core/src/test/awsService/appBuilder/explorer/samProject.test.ts +++ b/packages/core/src/test/awsService/appBuilder/explorer/samProject.test.ts @@ -48,7 +48,7 @@ describe('samProject', () => { assert.strictEqual(region, expectedRegion) }) - it('returns undefined give no stack name or region in samconfig file', async () => { + it('returns undefined given no stack name or region in samconfig file', async () => { await testFolder.write( 'samconfig.toml', generateSamconfigData({ @@ -71,24 +71,28 @@ describe('samProject', () => { const result = await wrapperCall(undefined) assert.deepStrictEqual(result, {}) - assertLogsContain('Error getting stack name or region information: No project folder found', false, 'warn') + assertLogsContain( + 'Error parsing stack name and/or region information: No project folder found', + false, + 'warn' + ) }) - it('returns empty object give no samconfig file found', async () => { + it('returns empty object given no samconfig file found', async () => { // simulate error when no samconfig.toml file in directory const result = await getStackName(projectRoot) assert.deepStrictEqual(result, {}) - assertLogsContain('No stack name or region information available in samconfig.toml', false, 'info') + assertLogsContain('Stack name and/or region information not found in samconfig.toml', false, 'info') }) - it('returns empty object give error parsing samconfig file', async () => { + it('returns empty object given error parsing samconfig file', async () => { // simulate error when parsinf samconfig.toml: missing quote or empty value await testFolder.write('samconfig.toml', samconfigInvalidData) const result = await getStackName(projectRoot) assert.deepStrictEqual(result, {}) - assertLogsContain('Error getting stack name or region information:', false, 'error') + assertLogsContain('Error parsing stack name and/or region information from samconfig.toml:', false, 'error') getTestWindow().getFirstMessage().assertError('Encountered an issue reading samconfig.toml') }) }) @@ -149,17 +153,6 @@ describe('samProject', () => { () => getApp(mockSamAppLocation), new ToolkitError(`Template at ${mockSamAppLocation.samTemplateUri.fsPath} is not valid`) ) - // try { - // await getApp(mockSamAppLocation) - // assert.fail('Test should not reach here. Expect ToolkitError thrown') - // } catch (error) { - // assert(cloudformationTryLoadSpy.calledOnce) - // assert(error instanceof ToolkitError) - // assert.strictEqual( - // error.message, - // `Template at ${mockSamAppLocation.samTemplateUri.fsPath} is not valid` - // ) - // } }) }) }) diff --git a/packages/core/src/test/awsService/appBuilder/utils.test.ts b/packages/core/src/test/awsService/appBuilder/utils.test.ts index 37ffac34863..d74cfc77802 100644 --- a/packages/core/src/test/awsService/appBuilder/utils.test.ts +++ b/packages/core/src/test/awsService/appBuilder/utils.test.ts @@ -294,9 +294,9 @@ describe('AppBuilder Utils', function () { } try { await runOpenTemplate(tNode as TreeNode) - assert.fail('No template provided') + assert.fail('SAM Template not found, cannot open template') } catch (err) { - assert.strictEqual((err as Error).message, 'No template provided') + assert.strictEqual((err as Error).message, 'SAM Template not found, cannot open template') } // Then assert(openCommand.neverCalledWith(sinon.match.has('fspath', sinon.match(/template.yaml/g)))) diff --git a/packages/core/src/test/awsService/appBuilder/walkthrough.test.ts b/packages/core/src/test/awsService/appBuilder/walkthrough.test.ts index 72dfb5c0ae2..fc1d6093b97 100644 --- a/packages/core/src/test/awsService/appBuilder/walkthrough.test.ts +++ b/packages/core/src/test/awsService/appBuilder/walkthrough.test.ts @@ -206,9 +206,9 @@ describe('AppBuilder Walkthrough', function () { try { // When await genWalkthroughProject('Visual', workspaceUri, undefined) - assert.fail('template.yaml already exist') + assert.fail('A file named template.yaml already exists in this path.') } catch (e) { - assert.equal((e as Error).message, 'template.yaml already exist') + assert.equal((e as Error).message, 'A file named template.yaml already exists in this path.') } // Then assert.equal(await fs.readFileText(vscode.Uri.joinPath(workspaceUri, 'template.yaml')), prevInfo) @@ -236,9 +236,9 @@ describe('AppBuilder Walkthrough', function () { try { // When await genWalkthroughProject('S3', workspaceUri, 'python') - assert.fail('template.yaml already exist') + assert.fail('A file named template.yaml already exists in this path.') } catch (e) { - assert.equal((e as Error).message, 'template.yaml already exist') + assert.equal((e as Error).message, 'A file named template.yaml already exists in this path.') } // Then no overwrite happens assert.equal(await fs.readFileText(vscode.Uri.joinPath(workspaceUri, 'template.yaml')), prevInfo) diff --git a/packages/core/src/test/shared/applicationBuilder/explorer/nodes/appNode.test.ts b/packages/core/src/test/shared/applicationBuilder/explorer/nodes/appNode.test.ts index 80d83a8303c..d3c9b32555c 100644 --- a/packages/core/src/test/shared/applicationBuilder/explorer/nodes/appNode.test.ts +++ b/packages/core/src/test/shared/applicationBuilder/explorer/nodes/appNode.test.ts @@ -157,7 +157,7 @@ describe('AppNode', () => { assert.strictEqual(resourceNode.id, 'placeholder') assert.strictEqual( resourceNode.resource, - '[Unable to load Resource tree for this App. Update SAM template]' + '[Unable to load resource tree for this app. Ensure SAM template is correct.]' ) assert(getAppStub.calledOnce) assert(getStackNameStub.notCalled) diff --git a/packages/core/src/test/shared/applicationBuilder/explorer/nodes/deployedNode.test.ts b/packages/core/src/test/shared/applicationBuilder/explorer/nodes/deployedNode.test.ts index 4917979fe1f..d9b5bd1c023 100644 --- a/packages/core/src/test/shared/applicationBuilder/explorer/nodes/deployedNode.test.ts +++ b/packages/core/src/test/shared/applicationBuilder/explorer/nodes/deployedNode.test.ts @@ -220,7 +220,10 @@ describe('generateDeployedNode', () => { // Check placeholder propertries const deployedResourceNode = deployedResourceNodes[0] as DeployedResourceNode assert.strictEqual(deployedResourceNode.id, 'placeholder') - assert.strictEqual(deployedResourceNode.resource, '[Failed to retrive deployed resource.]') + assert.strictEqual( + deployedResourceNode.resource, + '[Failed to retrieve deployed resource. Ensure correct stack name and region are in the samconfig.toml, and that your account is connected.]' + ) }) }) @@ -374,7 +377,7 @@ describe('generateDeployedNode', () => { // Check placeholder propertries const deployedResourceNode = deployedResourceNodes[0] as DeployedResourceNode assert.strictEqual(deployedResourceNode.id, 'placeholder') - assert.strictEqual(deployedResourceNode.resource, '[This resource is not yet supported.]') + assert.strictEqual(deployedResourceNode.resource, '[This resource is not yet supported in AppBuilder.]') }) }) }) diff --git a/packages/toolkit/.changes/next-release/Bug Fix-b033b55b-52a5-488a-a4a7-c3228232bca6.json b/packages/toolkit/.changes/next-release/Bug Fix-b033b55b-52a5-488a-a4a7-c3228232bca6.json new file mode 100644 index 00000000000..0c6b2f78b1d --- /dev/null +++ b/packages/toolkit/.changes/next-release/Bug Fix-b033b55b-52a5-488a-a4a7-c3228232bca6.json @@ -0,0 +1,4 @@ +{ + "type": "Bug Fix", + "description": "AppBuilder: Update error messaging to make more legible and actionable" +}