diff --git a/packages/amplify-provider-awscloudformation/src/__tests__/initialize-env.test.ts b/packages/amplify-provider-awscloudformation/src/__tests__/initialize-env.test.ts new file mode 100644 index 00000000000..b67a85aba65 --- /dev/null +++ b/packages/amplify-provider-awscloudformation/src/__tests__/initialize-env.test.ts @@ -0,0 +1,34 @@ +import { downloadZip } from '../zip-util'; +import { run } from '../initialize-env'; +import { $TSContext, AmplifyException } from 'amplify-cli-core'; + +jest.mock('../aws-utils/aws-s3'); +jest.mock('../zip-util'); + +const downloadZipMock = downloadZip as jest.MockedFunction; + +describe('initialize environment', () => { + const contextStub = { + amplify: { + pathManager: { + getAmplifyDirPath: jest.fn().mockReturnValue('some/path'), + getCurrentCloudBackendDirPath: jest.fn(), + getBackendDirPath: jest.fn(), + }, + }, + } as unknown as $TSContext; + it('throws AmplifyError if the deployment bucket does not exist', async () => { + downloadZipMock.mockRejectedValueOnce({ code: 'NoSuchBucket' }); + const actual = await expect(run(contextStub, {})).rejects; + actual.toBeInstanceOf(AmplifyException); + actual.toMatchInlineSnapshot( + `[EnvironmentNotInitializedError: Could not find a deployment bucket for the specified backend environment. This environment may have been deleted.]`, + ); + }); + + it('throws underlying error if the deployment bucket exists but fetching current-cloud-backend zip fails for some other reason', async () => { + const errStub = { code: 'SomethingElse' }; + downloadZipMock.mockRejectedValueOnce(errStub); + await expect(run(contextStub, {})).rejects.toEqual(errStub); + }); +}); diff --git a/packages/amplify-provider-awscloudformation/src/initialize-env.ts b/packages/amplify-provider-awscloudformation/src/initialize-env.ts index d850957761f..eeff4aca5fb 100644 --- a/packages/amplify-provider-awscloudformation/src/initialize-env.ts +++ b/packages/amplify-provider-awscloudformation/src/initialize-env.ts @@ -1,18 +1,4 @@ -/* eslint-disable max-depth */ -/* eslint-disable max-lines-per-function */ -/* eslint-disable prefer-const */ -/* eslint-disable no-param-reassign */ -/* eslint-disable no-return-await */ -/* eslint-disable consistent-return */ -/* eslint-disable no-continue */ -/* eslint-disable max-len */ -/* eslint-disable spellcheck/spell-checker */ -/* eslint-disable @typescript-eslint/explicit-function-return-type */ -/* eslint-disable func-style */ -/* eslint-disable no-restricted-syntax */ -/* eslint-disable @typescript-eslint/no-explicit-any */ -/* eslint-disable prefer-arrow/prefer-arrow-functions */ -import { $TSContext, $TSMeta, JSONUtilities, PathConstants, stateManager } from '@aws-amplify/amplify-cli-core'; +import { $TSContext, $TSMeta, AmplifyError, JSONUtilities, PathConstants, stateManager } from '@aws-amplify/amplify-cli-core'; import fs from 'fs-extra'; import glob from 'glob'; import _ from 'lodash'; @@ -38,9 +24,21 @@ export async function run(context: $TSContext, providerMetadata: $TSMeta) { const backendDir = context.amplify.pathManager.getBackendDirPath(); const s3 = await S3.getInstance(context); - const cfnItem = await new Cloudformation(context); - const file = await downloadZip(s3, tempDir, S3BackendZipFileName, undefined); - const unzippedDir = await extractZip(tempDir, file); + let currentCloudBackendZip: string; + try { + currentCloudBackendZip = await downloadZip(s3, tempDir, S3BackendZipFileName, undefined); + } catch (err) { + if (err?.code === 'NoSuchBucket') { + throw new AmplifyError('EnvironmentNotInitializedError', { + message: `Could not find a deployment bucket for the specified backend environment. This environment may have been deleted.`, + resolution: 'Make sure the environment has been initialized with "amplify init" or "amplify env add".', + }); + } + // if there was some other error, rethrow it + throw err; + } + + const unzippedDir = await extractZip(tempDir, currentCloudBackendZip); fs.removeSync(currentCloudBackendDir); @@ -74,9 +72,10 @@ export async function run(context: $TSContext, providerMetadata: $TSMeta) { fs.removeSync(tempDir); logger('run.cfn.updateamplifyMetaFileWithStackOutputs', [{ StackName: providerMetadata.StackName }])(); + const cfnItem = await new Cloudformation(context); await cfnItem.updateamplifyMetaFileWithStackOutputs(providerMetadata.StackName); - // Copy provider metadata from current-cloud-backend/amplify-meta to backend/ampliy-meta + // Copy provider metadata from current-cloud-backend/amplify-meta to backend/amplify-meta const currentAmplifyMeta = stateManager.getCurrentMeta(); const amplifyMeta = stateManager.getMeta();