UNPKG

devebot

Version:

Nodejs Microservice Framework

322 lines (317 loc) 11.8 kB
"use strict"; const lodash = require("lodash"); const path = require("path"); const Chalk = require("../utils/chalk"); const chores = require("../utils/chores"); const constx = require("../utils/constx"); const LoggingWrapper = require("./logging-wrapper"); const blockRef = chores.getBlockRef(__filename); const FRAMEWORK_PACKAGE_NAME = constx.FRAMEWORK.PACKAGE_NAME; const FRAMEWORK_BRIDGE_LABEL = "bridge"; const FRAMEWORK_PLUGIN_LABEL = "plugin"; function IssueInspector(params = {}) { const loggingWrapper = new LoggingWrapper(blockRef); const L = loggingWrapper.getLogger(); const T = loggingWrapper.getTracer(); L && L.has("silly") && L.log("silly", T && T.toMessage({ tags: [blockRef, "constructor-begin"], text: " + constructor start ..." })); const opStates = []; this.init = function () { return this.reset(); }; this.collect = function (info) { if (info instanceof Array) { Array.prototype.push.apply(opStates, info); } else { if (info && typeof info === "object") { opStates.push(info); } } return this; }; this.examine = function (options = {}) { const summary = lodash.reduce(opStates, function (store, item) { if (item.hasError) { store.numberOfErrors += 1; store.failedServices.push(item); } return store; }, { numberOfErrors: 0, failedServices: [] }); L && L.has("silly") && L.log("silly", T && T.add({ invoker: options.invoker, totalOfErrors: summary.numberOfErrors, errors: summary.failedServices }).toMessage({ tags: [blockRef, "examine", options.footmark], text: " - Total of errors: ${totalOfErrors}" })); return summary; }; this.barrier = function (options = {}) { const summary = this.examine(options); if (summary.numberOfErrors > 0) { const silent = _isSilentForced("issue-inspector", options); if (!silent) { _consoleError(chalk.errorHeader("[x] There are %s error(s) occurred during load:"), summary.numberOfErrors); lodash.forEach(summary.failedServices, function (fsv) { if (fsv.stage === "bootstrap") { switch (fsv.type) { case "appbox": case "application": case FRAMEWORK_PACKAGE_NAME: { _consoleError(chalk.errorMessage("--> [%s:%s] lauching bootstrap has failed, reasons:"), fsv.type, fsv.name); _consoleError(chalk.errorStack(" " + fsv.stack)); return; } case FRAMEWORK_PLUGIN_LABEL: { _consoleError(chalk.errorMessage("--> [%s:%s] loading plugin is failed, reasons:"), fsv.type, fsv.name); _consoleError(chalk.errorStack(" " + fsv.stack)); return; } case FRAMEWORK_BRIDGE_LABEL: { _consoleError(chalk.errorMessage("--> [%s:%s] loading bridge is failed, reasons:"), fsv.type, fsv.name); _consoleError(chalk.errorStack(" " + fsv.stack)); return; } } } if (fsv.stage === "package-version") { _consoleError(chalk.errorMessage("--> [%s:%s] cannot read the version, package.json not found or does not contain 'version'."), fsv.type, fsv.name); return; } if (fsv.stage === "manifest") { switch (fsv.type) { case "appbox": case "application": case FRAMEWORK_PACKAGE_NAME: { _consoleError(chalk.errorMessage("--> [%s:%s] loading manifest has failed, reasons:"), fsv.type, fsv.name); _consoleError(chalk.errorStack(" " + fsv.stack)); return; } case FRAMEWORK_PLUGIN_LABEL: { _consoleError(chalk.errorMessage("--> [%s:%s] loading plugin's manifest has failed, reasons:"), fsv.type, fsv.name); _consoleError(chalk.errorStack(" " + fsv.stack)); return; } case FRAMEWORK_BRIDGE_LABEL: { _consoleError(chalk.errorMessage("--> [%s:%s] loading bridge's manifest has failed, reasons:"), fsv.type, fsv.name); _consoleError(chalk.errorStack(" " + fsv.stack)); return; } } } if (fsv.stage === "naming") { switch (fsv.type) { case FRAMEWORK_PLUGIN_LABEL: { _consoleError(chalk.errorMessage("--> [%s:%s] resolving plugin-code is failed, reasons:"), fsv.type, fsv.name); _consoleError(chalk.errorStack(" " + fsv.stack)); return; } case FRAMEWORK_BRIDGE_LABEL: { _consoleError(chalk.errorMessage("--> [%s:%s] resolving bridge-code is failed, reasons:"), fsv.type, fsv.name); _consoleError(chalk.errorStack(" " + fsv.stack)); return; } } } if (fsv.stage === "config/upgrade") { switch (fsv.type) { default: { _consoleError(chalk.errorMessage("--> [%s:%s] migrating configure has been failed:"), fsv.type, fsv.name); _consoleError(chalk.errorStack(" " + fsv.stack)); return; } } } if (fsv.stage === "config/schema") { switch (fsv.type) { case "application": case FRAMEWORK_PACKAGE_NAME: case FRAMEWORK_PLUGIN_LABEL: { _consoleError(chalk.errorMessage("--> [%s:%s] plugin's configure is invalid, reasons:"), fsv.type, fsv.name); _consoleError(chalk.errorStack(" " + fsv.stack)); return; } case FRAMEWORK_BRIDGE_LABEL: { _consoleError(chalk.errorMessage("--> [%s:%s] bridge's configure is invalid, reasons:"), fsv.type, fsv.name); _consoleError(chalk.errorStack(" " + fsv.stack)); return; } } } if (fsv.stage === "instantiating") { switch (fsv.type) { case "ROUTINE": case "SERVICE": case "TRIGGER": { _consoleError(chalk.errorMessage("--> [%s:%s] new() is failed:"), fsv.type, fsv.name); _consoleError(chalk.errorStack(" " + fsv.stack)); return; } case "DIALECT": { _consoleError(chalk.errorMessage("--> [%s:%s/%s] new() is failed:"), fsv.type, fsv.code, fsv.name); _consoleError(chalk.errorStack(" " + fsv.stack)); return; } default: { _consoleError(chalk.errorMessage("--> %s"), JSON.stringify(fsv)); return; } } } if (fsv.stage === "check-methods") { switch (fsv.type) { case "TRIGGER": { _consoleError(chalk.errorMessage("--> [%s:%s] required method(s): %s not found"), fsv.type, fsv.name, JSON.stringify(fsv.methods)); return; } default: { _consoleError(chalk.errorMessage("--> %s"), JSON.stringify(fsv)); return; } } } switch (fsv.type) { case "CONFIG": { _consoleError(chalk.errorMessage("--> [%s] in (%s):"), fsv.type, fsv.file); _consoleError(chalk.errorStack(" " + fsv.stack)); break; } case "ROUTINE": case "SERVICE": case "TRIGGER": { _consoleError(chalk.errorMessage("--> [%s:%s] - %s in (%s):"), fsv.type, fsv.name, fsv.file, _buildPath(fsv.path, fsv.subDir)); _consoleError(chalk.errorStack(" " + fsv.stack)); break; } case "DIALECT": { _consoleError(chalk.errorMessage("--> [%s:%s/%s] in (%s):"), fsv.type, fsv.code, fsv.name, fsv.path); _consoleError(chalk.errorStack(" " + fsv.stack)); break; } case "application": { _consoleError(chalk.errorMessage("--> [%s:%s] - %s in (%s):"), fsv.type, fsv.name, fsv.file, _buildPath(fsv.path, fsv.subDir)); _consoleError(chalk.errorStack(" " + fsv.stack)); break; } default: { _consoleError(chalk.errorMessage("--> %s"), JSON.stringify(fsv)); break; } } }); } L && L.has("silly") && L.log("silly", T && T.add({ invoker: options.invoker, silent: silent, exitOnError: options.exitOnError !== false }).toMessage({ tags: [blockRef, "barrier", options.footmark], text: " - Program will be exited? (${exitOnError})" })); if (options.exitOnError !== false) { if (!silent) { _consoleWarn(chalk.warnHeader("[!] The program will exit now.")); _consoleWarn(chalk.warnMessage("... Please fix the issues and then retry again.")); } this.exit(1); } } }; this.exit = function (exitCode) { exitCode = lodash.isNumber(exitCode) ? exitCode : 0; L && L.has("silly") && L.log("silly", T && T.add({ exitCode }).toMessage({ tags: [blockRef, "exit"], text: "process.exit(${exitCode}) is invoked" })); switch (_fatalErrorReaction()) { case "exit": return _processExit(exitCode); case "exception": throw new Error("Fatal error, throw exception with code: " + exitCode); } if (!_skipProcessExit()) { _processExit(exitCode); } }; this.reset = function () { opStates.splice(0, opStates.length); return this; }; L && L.has("silly") && L.log("silly", T && T.toMessage({ tags: [blockRef, "constructor-end"], text: " - constructor has finished" })); } IssueInspector.argumentSchema = { "$id": "issueInspector", "type": "object", "properties": {} }; module.exports = IssueInspector; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ color chalks const chalk = new Chalk({ themes: { errorHeader: ["red", "bold"], errorMessage: ["red"], errorStack: ["grey"], warnHeader: ["yellow", "bold"], warnMessage: ["yellow"] } }); function _buildPath(basepath, subpath) { if (basepath) { return subpath ? path.join(basepath, subpath) : basepath; } return subpath || "-"; } function _isSilentForced(options) { return chores.isSilentForced("issue-inspector", options); } function _fatalErrorReaction() { // will return "exit" or "exception" return chores.fatalErrorReaction(); } function _skipProcessExit() { return chores.skipProcessExit(); } function _processExit() { return process.exit.apply(process, arguments); } const _consoleError = console.error.bind(console); const _consoleWarn = console.warn.bind(console); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ default instance let singleton; Object.defineProperty(IssueInspector, "instance", { get: function () { return singleton = singleton || new IssueInspector(); } });