1 | ;
|
2 | /*
|
3 | * Copyright (c) 2018, salesforce.com, inc.
|
4 | * All rights reserved.
|
5 | * SPDX-License-Identifier: BSD-3-Clause
|
6 | * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
7 | */
|
8 | Object.defineProperty(exports, "__esModule", { value: true });
|
9 | const kit_1 = require("@salesforce/kit");
|
10 | const ts_types_1 = require("@salesforce/ts-types");
|
11 | const messages_1 = require("./messages");
|
12 | /**
|
13 | * A class to manage all the keys and tokens for a message bundle to use with SfdxError.
|
14 | *
|
15 | * ```
|
16 | * SfdxError.create(new SfdxErrorConfig('MyPackage', 'apex', 'runTest').addAction('apexErrorAction1', [className]));
|
17 | * ```
|
18 | */
|
19 | class SfdxErrorConfig {
|
20 | /**
|
21 | * Create a new SfdxErrorConfig.
|
22 | * @param packageName The name of the package.
|
23 | * @param bundleName The message bundle.
|
24 | * @param errorKey The error message key.
|
25 | * @param errorTokens The tokens to use when getting the error message.
|
26 | * @param actionKey The action message key.
|
27 | * @param actionTokens The tokens to use when getting the action message(s).
|
28 | */
|
29 | constructor(packageName, bundleName, errorKey, errorTokens = [], actionKey, actionTokens) {
|
30 | this.actions = new Map();
|
31 | this.packageName = packageName;
|
32 | this.bundleName = bundleName;
|
33 | this.errorKey = errorKey;
|
34 | this.errorTokens = errorTokens;
|
35 | if (actionKey)
|
36 | this.addAction(actionKey, actionTokens);
|
37 | }
|
38 | /**
|
39 | * Set the error key.
|
40 | * @param key The key to set.
|
41 | * @returns {SfdxErrorConfig} For convenience `this` object is returned.
|
42 | */
|
43 | setErrorKey(key) {
|
44 | this.errorKey = key;
|
45 | return this;
|
46 | }
|
47 | /**
|
48 | * Set the error tokens.
|
49 | * @param tokens The tokens to set. For convenience `this` object is returned.
|
50 | */
|
51 | setErrorTokens(tokens) {
|
52 | this.errorTokens = tokens;
|
53 | return this;
|
54 | }
|
55 | /**
|
56 | * Add an error action to assist the user with a resolution. For convenience `this` object is returned.
|
57 | * @param actionKey The action key in the message bundle.
|
58 | * @param actionTokens The action tokens for the string.
|
59 | */
|
60 | addAction(actionKey, actionTokens = []) {
|
61 | this.actions.set(actionKey, actionTokens);
|
62 | return this;
|
63 | }
|
64 | /**
|
65 | * Load the messages using `Messages.loadMessages`. Returns the loaded messages.
|
66 | */
|
67 | load() {
|
68 | this.messages = messages_1.Messages.loadMessages(this.packageName, this.bundleName);
|
69 | return this.messages;
|
70 | }
|
71 | /**
|
72 | * Get the error message using messages.getMessage.
|
73 | * **Throws** If `errorMessages.load` was not called first.
|
74 | */
|
75 | getError() {
|
76 | if (!this.messages) {
|
77 | throw new SfdxError('SfdxErrorConfig not loaded.');
|
78 | }
|
79 | return this.messages.getMessage(this.errorKey, this.errorTokens);
|
80 | }
|
81 | /**
|
82 | * Get the action messages using messages.getMessage.
|
83 | * **@throws** If `errorMessages.load` was not called first.
|
84 | */
|
85 | getActions() {
|
86 | if (!this.messages) {
|
87 | throw new SfdxError('SfdxErrorConfig not loaded.');
|
88 | }
|
89 | if (this.actions.size === 0)
|
90 | return;
|
91 | const actions = [];
|
92 | this.actions.forEach((tokens, key) => {
|
93 | const messages = this.messages;
|
94 | if (messages) {
|
95 | actions.push(messages.getMessage(key, tokens));
|
96 | }
|
97 | });
|
98 | return actions;
|
99 | }
|
100 | /**
|
101 | * Remove all actions from this error config. Useful when reusing SfdxErrorConfig for other error messages within
|
102 | * the same bundle. For convenience `this` object is returned.
|
103 | */
|
104 | removeActions() {
|
105 | this.actions = new Map();
|
106 | return this;
|
107 | }
|
108 | }
|
109 | exports.SfdxErrorConfig = SfdxErrorConfig;
|
110 | /**
|
111 | * A generalized sfdx error which also contains an action. The action is used in the
|
112 | * CLI to help guide users past the error.
|
113 | *
|
114 | * To throw an error in a synchronous function you must either pass the error message and actions
|
115 | * directly to the constructor, e.g.
|
116 | *
|
117 | * ```
|
118 | * // To load a message bundle:
|
119 | * Messages.importMessagesDirectory(__dirname);
|
120 | * this.messages = Messages.loadMessages('myPackageName', 'myBundleName');
|
121 | * // Note that __dirname should contain a messages folder.
|
122 | *
|
123 | * // To throw an error associated with the message from the bundle:
|
124 | * throw SfdxError.create('myPackageName', 'myBundleName', 'MyErrorMessageKey', [messageToken1]);
|
125 | *
|
126 | * // To throw a non-bundle based error:
|
127 | * throw new SfdxError(myErrMsg, 'MyErrorName');
|
128 | * ```
|
129 | */
|
130 | class SfdxError extends kit_1.NamedError {
|
131 | // The create implementation function.
|
132 | static create(nameOrConfig, bundleName, key, tokens) {
|
133 | let errorConfig;
|
134 | if (ts_types_1.isString(nameOrConfig)) {
|
135 | errorConfig = new SfdxErrorConfig(nameOrConfig, ts_types_1.ensure(bundleName), ts_types_1.ensure(key), tokens);
|
136 | }
|
137 | else {
|
138 | errorConfig = nameOrConfig;
|
139 | }
|
140 | errorConfig.load();
|
141 | return new SfdxError(errorConfig.getError(), errorConfig.errorKey, errorConfig.getActions());
|
142 | }
|
143 | /**
|
144 | * Convert an Error to an SfdxError.
|
145 | * @param err The error to convert.
|
146 | */
|
147 | static wrap(err) {
|
148 | const sfdxError = new SfdxError(err.message, err.name);
|
149 | if (sfdxError.stack) {
|
150 | sfdxError.stack = sfdxError.stack.replace(`${err.name}: ${err.message}`, 'Outer stack:');
|
151 | sfdxError.stack = `${err.stack}\n${sfdxError.stack}`;
|
152 | }
|
153 | // If the original error has a code, use that instead of name.
|
154 | if (ts_types_1.hasString(err, 'code')) {
|
155 | sfdxError.code = err.code;
|
156 | }
|
157 | return sfdxError;
|
158 | }
|
159 | /**
|
160 | * Create an SfdxError.
|
161 | * @param message The error message.
|
162 | * @param name The error name. Defaults to 'SfdxError'.
|
163 | * @param actions The action message(s).
|
164 | * @param exitCode The exit code which will be used by SfdxCommand.
|
165 | * @param cause The underlying error that caused this error to be raised.
|
166 | */
|
167 | constructor(message, name, actions, exitCode, cause) {
|
168 | super(name || 'SfdxError', message, cause);
|
169 | this.actions = actions;
|
170 | this.exitCode = exitCode || 1;
|
171 | }
|
172 | get code() {
|
173 | return this._code || this.name;
|
174 | }
|
175 | set code(code) {
|
176 | this._code = code;
|
177 | }
|
178 | /**
|
179 | * Sets the name of the command. For convenience `this` object is returned.
|
180 | * @param commandName The command name.
|
181 | */
|
182 | setCommandName(commandName) {
|
183 | this.commandName = commandName;
|
184 | return this;
|
185 | }
|
186 | /**
|
187 | * An additional payload for the error. For convenience `this` object is returned.
|
188 | * @param data The payload data.
|
189 | */
|
190 | setData(data) {
|
191 | this.data = data;
|
192 | return this;
|
193 | }
|
194 | /**
|
195 | * Convert an {@link SfdxError} state to an object. Returns a plain object representing the state of this error.
|
196 | */
|
197 | toObject() {
|
198 | const obj = {
|
199 | name: this.name,
|
200 | message: this.message || this.name,
|
201 | exitCode: this.exitCode,
|
202 | actions: this.actions
|
203 | };
|
204 | if (this.commandName) {
|
205 | obj.commandName = this.commandName;
|
206 | }
|
207 | if (this.data) {
|
208 | obj.data = this.data;
|
209 | }
|
210 | return obj;
|
211 | }
|
212 | }
|
213 | exports.SfdxError = SfdxError;
|
214 | //# sourceMappingURL=sfdxError.js.map |
\ | No newline at end of file |