@salesforce/core
Version:
Core libraries to interact with SFDX projects, orgs, and APIs.
161 lines • 5.5 kB
JavaScript
"use strict";
/*
* Copyright (c) 2020, salesforce.com, inc.
* All rights reserved.
* Licensed under the BSD 3-Clause license.
* For full license text, see LICENSE.txt file in the repo root or https://opensource.org/licenses/BSD-3-Clause
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.SfError = void 0;
const ts_types_1 = require("@salesforce/ts-types");
/**
* A generalized sfdx error which also contains an action. The action is used in the
* CLI to help guide users past the error.
*
* To throw an error in a synchronous function you must either pass the error message and actions
* directly to the constructor, e.g.
*
* ```
* // To load a message bundle (Note that __dirname should contain a messages folder)
* Messages.importMessagesDirectory(__dirname);
* const messages = Messages.load('myPackageName', 'myBundleName');
*
* // To throw a non-bundle based error:
* throw new SfError(message.getMessage('myError'), 'MyErrorName');
* ```
*/
class SfError extends Error {
name;
/**
* Action messages. Hints to the users regarding what can be done to fix related issues.
*/
actions;
/**
* SfdxCommand can return this process exit code.
*/
exitCode;
/**
* The related context for this error.
*/
context;
// Additional data helpful for consumers of this error. E.g., API call result
data;
/**
* Some errors support `error.code` instead of `error.name`. This keeps backwards compatability.
*/
#code;
/**
* Create an SfError.
*
* @param message The error message.
* @param name The error name. Defaults to 'SfError'.
* @param actions The action message(s).
* @param exitCodeOrCause The exit code which will be used by SfdxCommand or he underlying error that caused this error to be raised.
* @param cause The underlying error that caused this error to be raised.
*/
constructor(message, name = 'SfError', actions, exitCodeOrCause, cause) {
if (typeof cause !== 'undefined' && !(cause instanceof Error)) {
throw new TypeError(`The cause, if provided, must be an instance of Error. Received: ${typeof cause}`);
}
super(message);
this.name = name;
this.cause = exitCodeOrCause instanceof Error ? exitCodeOrCause : cause;
if (actions?.length) {
this.actions = actions;
}
if (typeof exitCodeOrCause === 'number') {
this.exitCode = exitCodeOrCause;
}
else {
this.exitCode = 1;
}
}
get code() {
return this.#code ?? this.name;
}
set code(code) {
this.#code = code;
}
/** like the constructor, but takes an typed object and let you also set context and data properties */
static create(inputs) {
const error = new SfError(inputs.message, inputs.name, inputs.actions, inputs.exitCode, inputs.cause);
if (inputs.data) {
error.data = inputs.data;
}
if (inputs.context) {
error.context = inputs.context;
}
return error;
}
/**
* Convert an Error to an SfError.
*
* @param err The error to convert.
*/
static wrap(err) {
if ((0, ts_types_1.isString)(err)) {
return new SfError(err);
}
if (err instanceof SfError) {
return err;
}
const sfError = fromBasicError(err) ??
fromErrorLikeObject(err) ??
// something was thrown that wasn't error, error-like object or string. Convert it to an Error that preserves the information as the cause and wrap that.
SfError.wrap(new Error(`SfError.wrap received type ${typeof err} but expects type Error or string`, { cause: err }));
// If the original error has a code, use that instead of name.
if ((0, ts_types_1.hasString)(err, 'code')) {
sfError.code = err.code;
}
return sfError;
}
/**
* Sets the context of the error. For convenience `this` object is returned.
*
* @param context The command name.
*/
setContext(context) {
this.context = context;
return this;
}
/**
* An additional payload for the error. For convenience `this` object is returned.
*
* @param data The payload data.
*/
setData(data) {
this.data = data;
return this;
}
/**
* Convert an {@link SfError} state to an object. Returns a plain object representing the state of this error.
*/
toObject() {
return {
name: this.name,
message: this.message ?? this.name,
exitCode: this.exitCode,
...(this.actions?.length ? { actions: this.actions } : {}),
...(this.context ? { context: this.context } : {}),
...(this.data ? { data: this.data } : {}),
};
}
}
exports.SfError = SfError;
const fromBasicError = (err) => err instanceof Error ? SfError.create({ message: err.message, name: err.name, cause: err }) : undefined;
/* an object that is the result of spreading an Error or SfError */
const fromErrorLikeObject = (err) => {
if (!err || typeof err !== 'object') {
return undefined;
}
if (!('message' in err)) {
return undefined;
}
try {
return SfError.create(err);
}
catch {
return undefined;
}
};
//# sourceMappingURL=sfError.js.map