diff --git a/src/services/armService.test.ts b/src/services/armService.test.ts index a926ac12..e458276e 100644 --- a/src/services/armService.test.ts +++ b/src/services/armService.test.ts @@ -327,7 +327,7 @@ describe("Arm Service", () => { it("Throws more detailed error message upon failed ARM deployment", async () => { Deployments.prototype.createOrUpdate = jest.fn(() => Promise.reject(null)); - const lastDeploymentError: DeploymentExtendedError = { + const previousDeploymentError: DeploymentExtendedError = { code: "DeploymentFailed", message: "At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/arm-debug for usage details.", details: [ @@ -341,9 +341,9 @@ describe("Arm Service", () => { } ] } - ResourceService.prototype.getLastDeployment = jest.fn(() => Promise.resolve({ + ResourceService.prototype.getPreviousDeployment = jest.fn(() => Promise.resolve({ properties: { - error: lastDeploymentError + error: previousDeploymentError } })) as any; const deployment: ArmDeployment = { @@ -351,7 +351,7 @@ describe("Arm Service", () => { template: MockFactory.createTestArmTemplate() }; deployment.parameters.param1.value = "3" - const { code, message, details } = lastDeploymentError; + const { code, message, details } = previousDeploymentError; let errorPattern = [ code, message, @@ -401,5 +401,42 @@ describe("Arm Service", () => { expect(call[1]).toMatch(expectedDeploymentNameRegex); expect(call[2]).toEqual(expectedDeployment); }); + + it("Throws original error when there has not been a previous deployment", async () => { + const originalError = new Error("original error message"); + Deployments.prototype.createOrUpdate = jest.fn(() => Promise.reject(originalError)); + const previousDeploymentError: DeploymentExtendedError = { + code: "DeploymentFailed", + message: "At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/arm-debug for usage details.", + details: [ + { + code: "ServiceAlreadyExists", + message: "Api service already exists: abc-123-apim" + }, + { + code: "StorageAccountAlreadyTaken", + message: "The storage account named ABC123 is already taken." + } + ] + } + ResourceService.prototype.getPreviousDeployment = jest.fn(() => Promise.resolve(undefined)) as any; + const deployment: ArmDeployment = { + parameters: MockFactory.createTestParameters(), + template: MockFactory.createTestArmTemplate() + }; + deployment.parameters.param1.value = "3" + const { code, message, details } = previousDeploymentError; + let errorPattern = [ + code, + message, + details[0].code, + details[0].message, + details[1].code, + details[1].message + ].join(".*") + await expect(service.deployTemplate(deployment)) + .rejects + .toThrowError(originalError); + }); }); }); diff --git a/src/services/armService.ts b/src/services/armService.ts index cde93a4c..a574c01f 100644 --- a/src/services/armService.ts +++ b/src/services/armService.ts @@ -95,7 +95,7 @@ export class ArmService extends BaseService { this.applyEnvironmentVariables(deployment); const resourceService = new ResourceService(this.serverless, this.options); - const previous = await resourceService.getLastDeploymentTemplate(); + const previous = await resourceService.getPreviousDeploymentTemplate(); if (this.areDeploymentsEqual(deployment, previous)) { this.log("Generated template same as previous. Skipping ARM deployment"); @@ -130,11 +130,14 @@ export class ArmService extends BaseService { this.log("-> ARM deployment complete"); return result; } catch (err) { - const lastDeployment = await resourceService.getLastDeployment(); - const errorDetails: DeploymentExtendedError = lastDeployment.properties["error"]; - if (errorDetails) { - throw new Error(this.deploymentErrorToString(errorDetails)); + const previousDeployment = await resourceService.getPreviousDeployment(); + if (previousDeployment) { + const errorDetails: DeploymentExtendedError = previousDeployment.properties["error"]; + if (errorDetails) { + throw new Error(this.deploymentErrorToString(errorDetails)); + } } + throw err; } } diff --git a/src/services/resourceService.ts b/src/services/resourceService.ts index dac7acf7..6a032659 100644 --- a/src/services/resourceService.ts +++ b/src/services/resourceService.ts @@ -29,7 +29,7 @@ export class ResourceService extends BaseService { /** * Get the most recent resource group deployment */ - public async getLastDeployment() { + public async getPreviousDeployment() { const deployments = await this.getDeployments(); if (deployments && deployments.length) { return deployments[0]; @@ -39,8 +39,8 @@ export class ResourceService extends BaseService { /** * Get template from last resource group deployment */ - public async getLastDeploymentTemplate(): Promise { - const deployment = await this.getLastDeployment(); + public async getPreviousDeploymentTemplate(): Promise { + const deployment = await this.getPreviousDeployment(); if (!deployment || deployment.properties.provisioningState !== ArmTemplateProvisioningState.SUCCEEDED) { return; }