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

Commit a5b5a26

Browse files
[FEATURE] Add Specific error code for infra generate command (#471)
* [FEATURE] Add Specific error code for infra generate command * Update generate.ts * resolve confirm * Update errorStatusCode.ts Co-authored-by: Nate <[email protected]>
1 parent 5948d80 commit a5b5a26

File tree

5 files changed

+55
-32
lines changed

5 files changed

+55
-32
lines changed

src/commands/infra/generate.test.ts

+6-8
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ describe("test gitClone function", () => {
188188
it("negative Test", async () => {
189189
const git = simpleGit();
190190
git.clone = (): Promise<never> => {
191-
throw new Error("Error");
191+
throw Error("Error");
192192
};
193193

194194
await expect(gitClone(git, "source", "path")).rejects.toThrow();
@@ -221,7 +221,7 @@ describe("Validate remote git source", () => {
221221
});
222222
});
223223

224-
jest.spyOn(generate, "gitClone").mockReturnValue(Promise.resolve());
224+
jest.spyOn(generate, "gitClone").mockResolvedValue();
225225
jest.spyOn(generate, "createGenerated").mockReturnValue();
226226
jest.spyOn(generate, "checkTfvars").mockReturnValue();
227227
jest.spyOn(generate, "writeTfvarsFile").mockReturnValue();
@@ -302,9 +302,7 @@ describe("fetch execute function", () => {
302302
template: "",
303303
version: "",
304304
});
305-
jest
306-
.spyOn(generate, "generateConfig")
307-
.mockReturnValueOnce(Promise.resolve());
305+
jest.spyOn(generate, "generateConfig").mockResolvedValueOnce();
308306

309307
const exitFn = jest.fn();
310308
await execute(
@@ -394,9 +392,9 @@ describe("test validateRemoteSource function", () => {
394392
describe("test retryRemoteValidate function", () => {
395393
it("positive test", async () => {
396394
jest.spyOn(fsExtra, "removeSync").mockReturnValueOnce();
397-
jest.spyOn(generate, "gitClone").mockReturnValueOnce(Promise.resolve());
398-
jest.spyOn(generate, "gitFetchPull").mockReturnValueOnce(Promise.resolve());
399-
jest.spyOn(generate, "gitCheckout").mockReturnValueOnce(Promise.resolve());
395+
jest.spyOn(generate, "gitClone").mockResolvedValueOnce();
396+
jest.spyOn(generate, "gitFetchPull").mockResolvedValueOnce();
397+
jest.spyOn(generate, "gitCheckout").mockResolvedValueOnce();
400398
await retryRemoteValidate("source", "sourcePath", "safeLoggingUrl", "0.1");
401399
});
402400
it("negative test", async () => {

src/commands/infra/generate.ts

+27-11
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import {
2121
spkTemplatesPath,
2222
} from "./infra_common";
2323
import { copyTfTemplate } from "./scaffold";
24-
import { build as buildError } from "../../lib/errorBuilder";
24+
import { build as buildError, log as logError } from "../../lib/errorBuilder";
2525
import { errorStatusCode } from "../../lib/errorStatusCode";
2626

2727
interface CommandOptions {
@@ -68,8 +68,9 @@ export const execute = async (
6868
);
6969
await exitFn(0);
7070
} catch (err) {
71-
logger.error("Error occurred while generating project deployment files");
72-
logger.error(err);
71+
logError(
72+
buildError(errorStatusCode.CMD_EXE_ERR, "infra-generate-cmd-failed", err)
73+
);
7374
await exitFn(1);
7475
}
7576
};
@@ -119,7 +120,10 @@ export const validateDefinition = (
119120
return DefinitionYAMLExistence.PARENT_ONLY;
120121
}
121122

122-
throw new Error(`${DEFINITION_YAML} was not found in ${parentPath}`);
123+
throw buildError(errorStatusCode.ENV_SETTING_ERR, {
124+
errorKey: "infra-defn-yaml-not-found",
125+
values: [DEFINITION_YAML, parentPath],
126+
});
123127
};
124128

125129
export const getDefinitionYaml = (dir: string): InfraConfigYaml => {
@@ -175,11 +179,10 @@ export const validateTemplateSources = (
175179
);
176180
return source;
177181
}
178-
throw new Error(
179-
`The ${DEFINITION_YAML} file is invalid. \
180-
There is a missing field for it's sources. \
181-
Template: ${source.template} source: ${source.source} version: ${source.version}`
182-
);
182+
throw buildError(errorStatusCode.INCORRECT_DEFINITION, {
183+
errorKey: "infra-defn-yaml-invalid",
184+
values: [DEFINITION_YAML, source.template, source.source, source.version],
185+
});
183186
};
184187

185188
export const checkRemoteGitExist = async (
@@ -298,7 +301,7 @@ export const validateRemoteSource = async (
298301
} else {
299302
throw buildError(
300303
errorStatusCode.GIT_OPS_ERR,
301-
"infra-err-validating-remote-git",
304+
"infra-err-validating-remote-git-after-retry",
302305
err
303306
);
304307
}
@@ -310,7 +313,11 @@ export const validateRemoteSource = async (
310313
);
311314
}
312315
} else {
313-
throw err;
316+
throw buildError(
317+
errorStatusCode.GIT_OPS_ERR,
318+
"infra-err-validating-remote-git",
319+
err
320+
);
314321
}
315322
}
316323
};
@@ -353,13 +360,22 @@ export const generateConfigWithParentEqProjectPath = async (
353360
writeTfvarsFile(spkTfvarsObject, parentDirectory, SPK_TFVARS);
354361
await copyTfTemplate(templatePath, parentDirectory, true);
355362
} else {
363+
// Consider the case where the only common configuration is just
364+
// backend configuration, and no common variable configuration.
365+
// Thus, it is not "necessary" for a parent definition.yaml to
366+
// have a variables block in a multi-cluster.
356367
logger.warn(`Variables are not defined in the definition.yaml`);
357368
}
358369
if (parentInfraConfig.backend) {
359370
const backendTfvarsObject = generateTfvars(parentInfraConfig.backend);
360371
checkTfvars(parentDirectory, BACKEND_TFVARS);
361372
writeTfvarsFile(backendTfvarsObject, parentDirectory, BACKEND_TFVARS);
362373
} else {
374+
// Not all templates will require a remote backend
375+
// (i.e Bedrock's azure-simple).
376+
// If a remote backend is not configured for a template,
377+
// it will be impossible to be able to use spk infra in a
378+
// pipeline, but this can still work locally.
363379
logger.warn(
364380
`A remote backend configuration is not defined in the definition.yaml`
365381
);

src/commands/infra/scaffold.ts

+13-12
Original file line numberDiff line numberDiff line change
@@ -278,23 +278,24 @@ export const scaffold = (values: CommandOptions): void => {
278278
if (fs.existsSync(tfVariableFile)) {
279279
logger.info(`A ${VARIABLES_TF} file found : ${tfVariableFile}`);
280280

281-
const data: string = fs.readFileSync(tfVariableFile, "utf8");
281+
const data = fs.readFileSync(tfVariableFile, "utf8");
282282

283283
if (data) {
284284
const baseDef = generateClusterDefinition(values, backendData, data);
285+
// baseDef shall be always defined based on what generateClusterDefinition
286+
// function returns. hence we do not need to check if it is defined or not
285287
const definitionYaml = yaml.safeDump(baseDef);
286-
if (baseDef) {
287-
const confPath: string = path.format({
288-
base: DEFINITION_YAML,
289-
dir: values.name,
290-
root: "/ignored",
291-
});
292-
fs.writeFileSync(confPath, definitionYaml, "utf8");
293-
} else {
294-
throw Error(`Unable to generate cluster definition.`);
295-
}
288+
const confPath: string = path.format({
289+
base: DEFINITION_YAML,
290+
dir: values.name,
291+
root: "/ignored",
292+
});
293+
fs.writeFileSync(confPath, definitionYaml, "utf8");
296294
} else {
297-
throw Error(`Unable to read variable file: ${tfVariableFile}.`);
295+
throw buildError(errorStatusCode.ENV_SETTING_ERR, {
296+
errorKey: "infra-unable-read-var-file",
297+
values: [tfVariableFile],
298+
});
298299
}
299300
}
300301
} catch (err) {

src/lib/errorStatusCode.ts

+1
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ export enum errorStatusCode {
77
EXE_FLOW_ERR = 1002,
88
ENV_SETTING_ERR = 1010,
99
FILE_IO_ERR = 1011,
10+
INCORRECT_DEFINITION = 1012,
1011
GIT_OPS_ERR = 1100,
1112
}

src/lib/i18n.json

+8-1
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,16 @@
1616
"storageKeVaultName": "Enter key vault name (have the value as empty and hit enter key to skip)"
1717
},
1818
"errors": {
19-
"infra-scaffold-cmd-failed": "Scaffold Command was not successfully executed.",
19+
"infra-scaffold-cmd-failed": "Infra scaffold Command was not successfully executed.",
2020
"infra-scaffold-cmd-src-missing": "Value for source is required because it cannot be constructed with properties in spk-config.yaml. Provide value for source.",
2121
"infra-scaffold-cmd-values-missing": "Values for name, version and/or 'template were missing. Provide value for values for them.",
22+
23+
"infra-generate-cmd-failed": "Infra generate Command was not successfully executed.",
24+
25+
"infra-defn-yaml-not-found": "{0} was not found in {1}",
26+
"infra-defn-yaml-invalid": "The {0} file is invalid. There are missing fields. template: {1} source: {2} version: {3}.",
27+
"infra-unable-read-var-file": "Could read variable file: {0}. Make sure that it exists.",
28+
2229
"infra-err-validating-remote-git": "Could not determine error when validating remote git source.",
2330
"infra-err-retry-validating-remote-git": "Failure error thrown during retrying validating remote git source.",
2431
"infra-err-locate-tf-env": "Could not find Terraform environment. Ensure template path {0} exists.",

0 commit comments

Comments
 (0)