@interaktiv/mibuilder-core
Version:
Core libraries to interact with MiBuilder projects.
178 lines (141 loc) • 5.02 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.MiBuilderError = void 0;
var _dxl = require("@interaktiv/dxl");
var _errors = require("@interaktiv/errors");
var _mibuilderColors = require("@interaktiv/mibuilder-colors");
var _types = require("@interaktiv/types");
var _screen = _interopRequireDefault(require("@oclif/screen"));
var _indentString = _interopRequireDefault(require("indent-string"));
var _wrapAnsi = _interopRequireDefault(require("wrap-ansi"));
var _globalConfig = require("./config/global-config");
function getBang() {
let red;
try {
// eslint-disable-next-line prefer-destructuring
red = _mibuilderColors.color.red;
} catch (_a) {
red = s => s;
}
return red(_dxl.PLATFORM_WINDOWS ? '»' : '›');
}
/**
* A generalized mibuilder error which also contains an action. The action is
* used in the CLI to help guide users past the error.
*
* ```
* // To throw an error:
* throw new MiBuilderError(myErrMsg, 'MyErrorName');
* ```
*/
class MiBuilderError extends _errors.NamedError {
/**
* Convert an Error to an MiBuilderError.
*
* @param {Object<Error>} err The error to convert.
* @return {Object<MiBuilderError>} this
*/
static wrap(err) {
if ((0, _types.isString)(err)) return new MiBuilderError(err);
const mibuilderError = new MiBuilderError(err.message, err.name);
if (mibuilderError.stack) {
mibuilderError.stack = mibuilderError.stack.replace(`${err.name}: ${err.message}`, '\nOuter stack:');
mibuilderError.stack = `${err.stack}\n${mibuilderError.stack}`;
} // If the original error has a code, use that instead of name.
if ((0, _types.hasString)(err, 'code')) mibuilderError.code = err.code;
mibuilderError.cause = err;
return mibuilderError;
}
/**
* Create an MiBuilderError.
*
* @param {String} message The error message.
* @param {String} [name] The error name. Defaults to 'MiBuilderError'.
* @param {String[]} [actions] The action message(s).
* @param {Number} [exitCode] The exit code which will be used by MiBuilderCommand.
* @param {String} [cause] The underlying error that caused this error to be raised.
*/
constructor(message, name, actions, exitCode, cause) {
super(name || 'MiBuilderError', message, cause);
this.actions = actions;
this.exitCode = exitCode || 1;
}
get code() {
return this._code || this.name;
}
set code(code) {
this._code = code;
}
/**
* Sets the name of the command. For convenience `this` object is returned.
*
* @param {String} commandName The command name.
* @return {Object<MiBuilderError>} this
*/
setCommandName(commandName) {
this.commandName = commandName;
return this;
}
/**
* An additional payload for the error. For convenience `this` object is
* returned.
*
* @param {Object} data The payload data.
* @return {Object<MiBuilderError>} this
*/
setData(data) {
this.data = data;
return this;
}
/**
* Convert an {@link MiBuilderError} state to an object. Returns a plain
* object representing the state of this error.
*
* @return {Object} This as a plain object
*/
toObject() {
const obj = {
name: this.name,
message: this.message || this.name,
exitCode: this.exitCode,
actions: this.actions
};
if (this.commandName) obj.commandName = this.commandName;
if (this.data) obj.data = this.data;
return obj;
}
/**
* Format errors and actions for human consumption. Adds 'ERROR running
* <command name>' and outputs all errors in red. When there are actions, we
* add 'Try this:' in blue followed by each action in red on its own line.
*
* @return {string} Returns decorated message
*/
render() {
let output = `Error: ${this.message}`; // Format any actions.
if ((0, _types.get)(this, 'actions.length')) {
output = `${output}\n\n${_mibuilderColors.color.blue(_mibuilderColors.color.bold('Versuche folgendes:'))}`;
if (this.actions) {
output = this.actions.reduce((actionsOutput, action) => `${actionsOutput}\n${_mibuilderColors.color.red(action)}`, output);
}
}
output = (0, _wrapAnsi.default)(output, _screen.default.errtermwidth - 6, {
trim: false,
hard: true
});
output = (0, _indentString.default)(output, 3);
output = (0, _indentString.default)(output, 1, {
indent: getBang(),
includeEmptyLines: true
});
output = (0, _indentString.default)(output, 1);
if ((this.fullStack || this.stack) && (0, _globalConfig.getEnvironmentMode)() === _globalConfig.MODE_DEVELOPMENT) {
output += (0, _indentString.default)(_mibuilderColors.color.red(`\n\n*** Internal Diagnostic ***\n\n${this.fullStack || this.stack}\n\n******\n`), 5);
}
return `\n${output}`;
}
}
exports.MiBuilderError = MiBuilderError;