Skip to content
This repository was archived by the owner on Apr 13, 2020. It is now read-only.

Commit 57d23a6

Browse files
authored
[FEATURE] have error code for deployment get command (#511)
* [FEATURE] have error code for deployment get command * Update i18n.json * Update get.ts
1 parent 5cbb60c commit 57d23a6

File tree

3 files changed

+123
-126
lines changed

3 files changed

+123
-126
lines changed

src/commands/deployment/get.test.ts

+13-13
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import * as AzureDevOpsRepo from "spektate/lib/repository/IAzureDevOpsRepo";
55
import * as GitHub from "spektate/lib/repository/IGitHub";
66
import { ITag } from "spektate/lib/repository/Tag";
77
import { loadConfiguration } from "../../config";
8+
import { getErrorMessage } from "../../lib/errorBuilder";
89
import { deepClone } from "../../lib/util";
910
import {
1011
disableVerboseLogging,
@@ -181,13 +182,14 @@ describe("Test validateValues function", () => {
181182
it("negative test: valid values with top = -5", () => {
182183
const mockedValues = getMockedValues();
183184
mockedValues.top = "-5";
184-
try {
185+
expect(() => {
185186
validateValues(mockedValues);
186-
} catch (e) {
187-
expect(e.message).toBe(
188-
"value for top option has to be a positive number"
189-
);
190-
}
187+
}).toThrow(
188+
getErrorMessage({
189+
errorKey: "introspect-get-cmd-err-validation-top-num",
190+
values: ["-5"],
191+
})
192+
);
191193
});
192194
});
193195

@@ -251,13 +253,11 @@ describe("Get deployments", () => {
251253
it("getDeploymentsBasedOnFilters throw error", async () => {
252254
jest
253255
.spyOn(Deployment, "getDeploymentsBasedOnFilters")
254-
.mockReturnValueOnce(Promise.reject("Error"));
255-
try {
256-
await getDeployments(initObject, MOCKED_VALUES);
257-
expect(true).toBe(false);
258-
} catch (e) {
259-
expect(e.message).toBe("Error");
260-
}
256+
.mockRejectedValueOnce(Error("Error"));
257+
258+
await expect(getDeployments(initObject, MOCKED_VALUES)).rejects.toThrow(
259+
getErrorMessage("introspect-get-cmd-get-deployments-err")
260+
);
261261
});
262262
it("postive test", async () => {
263263
jest

src/commands/deployment/get.ts

+103-112
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@ import {
2020
import { ITag } from "spektate/lib/repository/Tag";
2121
import { Config } from "../../config";
2222
import { build as buildCmd, exit as exitCmd } from "../../lib/commandBuilder";
23+
import { build as buildError, log as logError } from "../../lib/errorBuilder";
24+
import { errorStatusCode } from "../../lib/errorStatusCode";
2325
import { isIntegerString } from "../../lib/validator";
2426
import { logger } from "../../logger";
2527
import decorator from "./get.decorator.json";
2628
import { IPullRequest } from "spektate/lib/repository/IPullRequest";
2729

28-
const promises: Promise<IPullRequest | undefined>[] = [];
30+
const promises: Promise<void>[] = [];
2931
const pullRequests: { [id: string]: IPullRequest } = {};
3032
/**
3133
* Output formats to display service details
@@ -104,7 +106,10 @@ export const validateValues = (opts: CommandOptions): ValidatedOptions => {
104106
if (isIntegerString(opts.top)) {
105107
top = parseInt(opts.top, 10);
106108
} else {
107-
throw new Error("value for top option has to be a positive number");
109+
throw buildError(errorStatusCode.VALIDATION_ERR, {
110+
errorKey: "introspect-get-cmd-err-validation-top-num",
111+
values: [opts.top],
112+
});
108113
}
109114
}
110115

@@ -141,8 +146,9 @@ export const initialize = async (): Promise<InitObject> => {
141146
!config.introspection.azure.partition_key ||
142147
!config.introspection.azure.key
143148
) {
144-
throw Error(
145-
"You need to run `spk init` and `spk deployment onboard` to configure `spk."
149+
throw buildError(
150+
errorStatusCode.VALIDATION_ERR,
151+
"introspect-get-cmd-missing-vals"
146152
);
147153
}
148154

@@ -178,50 +184,42 @@ export const initialize = async (): Promise<InitObject> => {
178184
* Gets cluster sync statuses
179185
* @param initObj captures keys and objects during the initialization process
180186
*/
181-
export const getClusterSyncStatuses = (
187+
export const getClusterSyncStatuses = async (
182188
initObj: InitObject
183189
): Promise<ITag[] | undefined> => {
184-
return new Promise((resolve, reject) => {
185-
try {
186-
if (initObj.manifestRepo && initObj.manifestRepo.includes("azure.com")) {
187-
const manifestUrlSplit = initObj.manifestRepo.split("/");
188-
const manifestRepo: IAzureDevOpsRepo = {
189-
org: manifestUrlSplit[3],
190-
project: manifestUrlSplit[4],
191-
repo: manifestUrlSplit[6],
192-
};
193-
getAzureManifestSyncState(manifestRepo, initObj.accessToken)
194-
.then((syncCommits: ITag[]) => {
195-
resolve(syncCommits);
196-
})
197-
.catch((e) => {
198-
reject(e);
199-
});
200-
} else if (
201-
initObj.manifestRepo &&
202-
initObj.manifestRepo.includes("github.com")
203-
) {
204-
const manifestUrlSplit = initObj.manifestRepo.split("/");
205-
const manifestRepo: IGitHub = {
206-
reponame: manifestUrlSplit[4],
207-
username: manifestUrlSplit[3],
208-
};
209-
210-
getGithubManifestSyncState(manifestRepo, initObj.accessToken)
211-
.then((syncCommits: ITag[]) => {
212-
resolve(syncCommits);
213-
})
214-
.catch((e) => {
215-
reject(e);
216-
});
217-
} else {
218-
resolve();
219-
}
220-
} catch (err) {
221-
logger.error(err);
222-
reject(err);
190+
try {
191+
if (initObj.manifestRepo && initObj.manifestRepo.includes("azure.com")) {
192+
const manifestUrlSplit = initObj.manifestRepo.split("/");
193+
const manifestRepo: IAzureDevOpsRepo = {
194+
org: manifestUrlSplit[3],
195+
project: manifestUrlSplit[4],
196+
repo: manifestUrlSplit[6],
197+
};
198+
return await getAzureManifestSyncState(manifestRepo, initObj.accessToken);
199+
} else if (
200+
initObj.manifestRepo &&
201+
initObj.manifestRepo.includes("github.com")
202+
) {
203+
const manifestUrlSplit = initObj.manifestRepo.split("/");
204+
const manifestRepo: IGitHub = {
205+
reponame: manifestUrlSplit[4],
206+
username: manifestUrlSplit[3],
207+
};
208+
209+
return await getGithubManifestSyncState(
210+
manifestRepo,
211+
initObj.accessToken
212+
);
213+
} else {
214+
return undefined;
223215
}
224-
});
216+
} catch (err) {
217+
throw buildError(
218+
errorStatusCode.GIT_OPS_ERR,
219+
"introspect-get-cmd-cluster-sync-stat-err",
220+
err
221+
);
222+
}
225223
};
226224

227225
/**
@@ -231,22 +229,23 @@ export const getClusterSyncStatuses = (
231229
* @param deployment deployment for which PR has to be fetched
232230
* @param initObj initialization object
233231
*/
234-
export const fetchPRInformation = (
232+
export const fetchPRInformation = async (
235233
deployment: IDeployment,
236234
initObj: InitObject
237-
): void => {
235+
): Promise<void> => {
238236
if (deployment.hldRepo && deployment.pr) {
239237
const repo = getRepositoryFromURL(deployment.hldRepo);
240238
const strPr = deployment.pr.toString();
241239

242240
if (repo) {
243-
const promise = fetchPR(repo, strPr, initObj.accessToken);
244-
promise.then((pr) => {
241+
try {
242+
const pr = await fetchPR(repo, strPr, initObj.accessToken);
245243
if (pr) {
246244
pullRequests[strPr] = pr;
247245
}
248-
});
249-
promises.push(promise);
246+
} catch (err) {
247+
logger.warn(`Could not get PR ${strPr} information: ` + err);
248+
}
250249
}
251250
}
252251
};
@@ -261,7 +260,9 @@ export const getPRs = (
261260
deployments: IDeployment[] | undefined,
262261
initObj: InitObject
263262
): void => {
264-
(deployments || []).forEach((d) => fetchPRInformation(d, initObj));
263+
(deployments || []).forEach((d) => {
264+
promises.push(fetchPRInformation(d, initObj));
265+
});
265266
};
266267

267268
/**
@@ -475,79 +476,68 @@ export const printDeployments = (
475476
* @param syncStatuses cluster sync statuses,
476477
* @param initObj initialization object
477478
*/
478-
export const displayDeployments = (
479+
export const displayDeployments = async (
479480
values: ValidatedOptions,
480481
deployments: IDeployment[] | undefined,
481482
syncStatuses: ITag[] | undefined,
482483
initObj: InitObject
483484
): Promise<IDeployment[]> => {
484-
return new Promise((resolve, reject) => {
485-
if (values.outputFormat === OUTPUT_FORMAT.WIDE) {
486-
getPRs(deployments, initObj);
487-
}
488-
if (values.outputFormat === OUTPUT_FORMAT.JSON) {
489-
console.log(JSON.stringify(deployments, null, 2));
490-
resolve(deployments);
491-
} else {
492-
Promise.all(promises)
493-
.then(() => {
494-
printDeployments(
495-
deployments,
496-
values.outputFormat,
497-
values.nTop,
498-
syncStatuses
499-
);
500-
resolve(deployments);
501-
})
502-
.catch((e) => {
503-
reject(e);
504-
});
505-
}
506-
});
485+
if (values.outputFormat === OUTPUT_FORMAT.WIDE) {
486+
getPRs(deployments, initObj);
487+
}
488+
489+
if (values.outputFormat === OUTPUT_FORMAT.JSON) {
490+
console.log(JSON.stringify(deployments, null, 2));
491+
return deployments || [];
492+
}
493+
494+
await Promise.all(promises);
495+
printDeployments(deployments, values.outputFormat, values.nTop, syncStatuses);
496+
return deployments || [];
507497
};
508498

509499
/**
510500
* Gets a list of deployments for the specified filters
511501
* @param initObj captures keys and objects during the initialization process
512502
* @param values validated command line values
513503
*/
514-
export const getDeployments = (
504+
export const getDeployments = async (
515505
initObj: InitObject,
516506
values: ValidatedOptions
517507
): Promise<IDeployment[]> => {
518-
const syncStatusesPromise = getClusterSyncStatuses(initObj);
519-
const deploymentsPromise = getDeploymentsBasedOnFilters(
520-
initObj.accountName,
521-
initObj.key,
522-
initObj.tableName,
523-
initObj.partitionKey,
524-
initObj.srcPipeline,
525-
initObj.hldPipeline,
526-
initObj.clusterPipeline,
527-
values.env,
528-
values.imageTag,
529-
values.buildId,
530-
values.commitId,
531-
values.service,
532-
values.deploymentId
533-
);
534-
return new Promise((resolve, reject) => {
535-
Promise.all([deploymentsPromise, syncStatusesPromise])
536-
.then(async (tuple: [IDeployment[] | undefined, ITag[] | undefined]) => {
537-
const deployments: IDeployment[] | undefined = tuple[0];
538-
const syncStatuses: ITag[] | undefined = tuple[1];
539-
const displayedDeployments = await displayDeployments(
540-
values,
541-
deployments,
542-
syncStatuses,
543-
initObj
544-
);
545-
resolve(displayedDeployments);
546-
})
547-
.catch((e) => {
548-
reject(new Error(e));
549-
});
550-
});
508+
try {
509+
const syncStatusesPromise = getClusterSyncStatuses(initObj);
510+
const deploymentsPromise = getDeploymentsBasedOnFilters(
511+
initObj.accountName,
512+
initObj.key,
513+
initObj.tableName,
514+
initObj.partitionKey,
515+
initObj.srcPipeline,
516+
initObj.hldPipeline,
517+
initObj.clusterPipeline,
518+
values.env,
519+
values.imageTag,
520+
values.buildId,
521+
values.commitId,
522+
values.service,
523+
values.deploymentId
524+
);
525+
526+
const tuple: [
527+
IDeployment[] | undefined,
528+
ITag[] | undefined
529+
] = await Promise.all([deploymentsPromise, syncStatusesPromise]);
530+
const deployments: IDeployment[] | undefined = tuple[0];
531+
const syncStatuses: ITag[] | undefined = tuple[1];
532+
533+
return await displayDeployments(values, deployments, syncStatuses, initObj);
534+
} catch (err) {
535+
throw buildError(
536+
errorStatusCode.EXE_FLOW_ERR,
537+
"introspect-get-cmd-get-deployments-err",
538+
err
539+
);
540+
}
551541
};
552542

553543
/**
@@ -591,8 +581,9 @@ export const execute = async (
591581
await exitFn(0);
592582
}
593583
} catch (err) {
594-
logger.error(`Error occurred while getting deployment(s)`);
595-
logger.error(err);
584+
logError(
585+
buildError(errorStatusCode.CMD_EXE_ERR, "introspect-get-cmd-failed", err)
586+
);
596587
await exitFn(1);
597588
}
598589
};

src/lib/i18n.json

+7-1
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,18 @@
129129
"introspect-validate-cmd-valid-exception": "Error was caught during validation.",
130130
"introspect-validate-cmd-write-pipeline": "Error writing data to service introspection.",
131131

132+
"introspect-get-cmd-failed": "Deployment validate get was not successfully executed.",
133+
"introspect-get-cmd-err-validation-top-num": "Could not execute command because value for top option {0} is not apositive number. Provide a positive number for port.",
134+
"introspect-get-cmd-missing-vals": "Configuration for storage account and DevOps pipeline were missing. Initialize the spk tool with the right configuration.",
135+
"introspect-get-cmd-cluster-sync-stat-err": "Could not get cluster sync status.",
136+
"introspect-get-cmd-get-deployments-err": "Could not get deployments.",
137+
132138
"introspect-dashboard-cmd-failed": "Deployment dashboard command was not successfully executed.",
133139
"introspect-dashboard-cmd-invalid-port": "value for port option has to be a valid port number. Enter a valid port number.",
134140
"introspect-dashboard-cmd-missing-vals": "Configuration for storage account and DevOps pipeline were missing. Initialize the spk tool with the right configuration.",
135141
"introspect-dashboard-cmd-kill-docker-container": "Could not kill dashboard docker containers.",
136142
"introspect-dashboard-cmd-get-env": "Could not get environment parameters.",
137-
"introspect-dashboard-cmd-launch-pre-req-err": "Requirements to launch dashboard were not met",
143+
"introspect-dashboard-cmd-launch-pre-req-err": "Requirements to launch dashboard were not met.",
138144
"introspect-dashboard-cmd-launch-err": "Could not launch dashboard docker container.",
139145

140146
"az-cli-login-err": "Could not login through azure cli.",

0 commit comments

Comments
 (0)