Skip to content

Commit

Permalink
fix: Throw original error if no previous deployments (#324)
Browse files Browse the repository at this point in the history
If a first-time deployment fails, it will crash with a weird error because the last deployment is undefined. This handles that scenario.
  • Loading branch information
tbarlow12 authored Sep 9, 2019
1 parent d46ef41 commit 6787f59
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 12 deletions.
45 changes: 41 additions & 4 deletions src/services/armService.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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: [
Expand All @@ -341,17 +341,17 @@ 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 = {
parameters: MockFactory.createTestParameters(),
template: MockFactory.createTestArmTemplate()
};
deployment.parameters.param1.value = "3"
const { code, message, details } = lastDeploymentError;
const { code, message, details } = previousDeploymentError;
let errorPattern = [
code,
message,
Expand Down Expand Up @@ -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);
});
});
});
13 changes: 8 additions & 5 deletions src/services/armService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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;
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/services/resourceService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand All @@ -39,8 +39,8 @@ export class ResourceService extends BaseService {
/**
* Get template from last resource group deployment
*/
public async getLastDeploymentTemplate(): Promise<ArmDeployment> {
const deployment = await this.getLastDeployment();
public async getPreviousDeploymentTemplate(): Promise<ArmDeployment> {
const deployment = await this.getPreviousDeployment();
if (!deployment || deployment.properties.provisioningState !== ArmTemplateProvisioningState.SUCCEEDED) {
return;
}
Expand Down

0 comments on commit 6787f59

Please sign in to comment.