From 6a11cbee3cabb6399f0261802551f5ace439c604 Mon Sep 17 00:00:00 2001 From: Dennis Seah Date: Thu, 2 Apr 2020 23:04:17 -0700 Subject: [PATCH] [DOC] on creating and throwing error (#502) --- guides/command-implementation.md | 24 +----- guides/error-handling.md | 133 +++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+), 22 deletions(-) create mode 100644 guides/error-handling.md diff --git a/guides/command-implementation.md b/guides/command-implementation.md index d03e47fd9..f8424abfe 100644 --- a/guides/command-implementation.md +++ b/guides/command-implementation.md @@ -115,25 +115,5 @@ E.g. 3. All error shall be created with the error builder, https://github.com/CatalystCode/spk/blob/master/src/lib/errorBuilder.ts so that we can generate the exception chain. In this manner, we can precisely - know the root cause of the problem. Error shall be logged at the end of the - command like this - -``` -export const execute = async ( - config: ConfigYaml, - opts: CommandOptions, - exitFn: (status: number) => Promise -): Promise => { - try { - ...; - await exitFn(0); - } catch (err) { - logError( - buildError(errorStatusCode.CMD_EXE_ERR, "infra-scaffold-cmd-failed", err) - ); - await exitFn(1); - } -}; -``` - -[Reference](../technical-docs/designs/exceptionHandling.md) + know the root cause of the problem. For more information, refer to + [error handling](./error-handling.md). diff --git a/guides/error-handling.md b/guides/error-handling.md new file mode 100644 index 000000000..90da109c8 --- /dev/null +++ b/guides/error-handling.md @@ -0,0 +1,133 @@ +# Error Handling + +## Objectives + +1. All errors are trace-able. That's from the error messages, we are able to + figure out the execution path (many times, it is not appropriate to dump + stack traces) and root cause(s). +2. An unique status code for each error so that user understand the error domain + which can be `validation error`, `Azure storage management error`, + `git operations related error`, etc. +3. Allows for localization of error message in future. + +## Coding details + +### imports + +```javascript +import { build as buildError } from ”../lib/errorBuilder"; +import { errorStatusCode } from "../lib/errorStatusCode"; +``` + +`src/lib/errorBuilder` is the error builder. `src/lib/errorStatusCode` contains +an enum of error type + +### throw + +#### case 1 + +```javascript +throw buildError(errorStatusCode., + ""); +``` + +example + +```javascript +throw buildError(errorStatusCode.GIT_OPS_ERR, "infra-err-git-clone-failed"); +``` + +and in `src/lib/i18n.json`, we have an entry + +``` +... +"infra-err-git-clone-failed": "Could not clone the source remote repository. The remote repo might not exist or you did not have the rights to access it", +... +``` + +#### case 2 + +where we have placeholder in error message + +```javascript +throw buildError(errorStatusCode., { + errorKey: "", + values: [sourcePath] +}); +``` + +and in `src/lib/i18n.json`, we have an entry + +``` +... +"infra-git-source-no-exist": "Source path, {0} did not exist.", +... +``` + +#### case 3 + +where we nest an error into current error + +```javascript +throw buildError(errorStatusCode., + "", err); +``` + +example + +```javascript +try { + +} catch (err) { + throw buildError(errorStatusCode.GIT_OPS_ERR, + "hld-reconcile-err-helm-add", err); + } +} +``` + +and in `src/lib/i18n.json`, we have an entry + +``` +... +hld-reconcile-err-helm-add": "Error adding helm chart", +... +``` + +### write to log before exiting + +This will write the entire error chain to the log. example + +``` +import { build as buildError, log as logError } from "../../lib/errorBuilder"; +import { errorStatusCode } from "../../lib/errorStatusCode"; + +... +export const execute = async ( + opts: CommandOptions, + exitFn: (status: number) => Promise +): Promise => { + try { + ... + await exitFn(0); + } catch (err) { + logError( + buildError( + errorStatusCode.CMD_EXE_ERR, + "introspect-create-cmd-failed", + err + ) + ); + await exitFn(1); + } +}; +``` + +We build a final error with `errorStatusCode.CMD_EXE_ERR`, and include the `err` +object. `err` may also include other errors. And we write this final error to +log with `logError` function. + +# Appendix + +## Reference + +1. https://github.com/CatalystCode/spk/blob/master/technical-docs/designs/exceptionHandling.md