UNPKG

backtrace-node

Version:
294 lines 12.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var crypto_1 = require("crypto"); var application_1 = require("../const/application"); var machineId_1 = require("../helpers/machineId"); var moduleResolver_1 = require("../helpers/moduleResolver"); var processHelper_1 = require("../helpers/processHelper"); var utils_1 = require("../utils"); var backtraceStackTrace_1 = require("./backtraceStackTrace"); /** * BacktraceReport describe current exception/message payload message to Backtrace */ var BacktraceReport = /** @class */ (function () { /** * Create new BacktraceReport - report information that will collect information * for Backtrace. * * Possible existing scenarios: * arg1: error + arg2: attributes = all required * arg1: object, arg2: nothing * * @param err Error or message - content to report * @param attributes Report attributes dictionary * @param attachments Report attachments that Backtrace will send to API */ function BacktraceReport(data, clientAttributes, attachments) { if (data === void 0) { data = ''; } if (clientAttributes === void 0) { clientAttributes = {}; } if (attachments === void 0) { attachments = []; } this.data = data; this.clientAttributes = clientAttributes; this.attachments = attachments; // reprot id this.uuid = this.generateUuid(); // timestamp this.timestamp = utils_1.currentTimestamp(); // lang this.lang = application_1.LANG; // environment version this.langVersion = process.version; // Backtrace-ndoe name this.agent = application_1.APP_NAME; // Backtrace-node version this.agentVersion = application_1.VERSION; // main thread name this.mainThread = application_1.THREAD; this.classifiers = []; this._symbolication = false; /** * Current report attributes */ this.attributes = {}; /** * Backtrace complex objet */ this.annotations = {}; this.tabWidth = 8; this.contextLineCount = 200; if (!clientAttributes) { clientAttributes = {}; } this.splitAttributesFromAnnotations(clientAttributes); if (!attachments) { attachments = []; } this.setError(data); } Object.defineProperty(BacktraceReport.prototype, "symbolication", { set: function (symbolication) { this._symbolication = symbolication; }, enumerable: true, configurable: true }); Object.defineProperty(BacktraceReport.prototype, "symbolicationMap", { set: function (symbolMap) { if (!symbolMap) { throw new Error('Symbolication map is undefined'); } if (!Array.isArray(symbolMap)) { throw new TypeError('Invalid type of symbolication map'); } var invalidValues = symbolMap.some(function (n) { return !n.file || !n.uuid; }); if (invalidValues) { throw new TypeError('Symbolication map contains invalid values - missing file or uuid value'); } this._symbolicationMap = symbolMap; }, enumerable: true, configurable: true }); /** * Check if report contains exception information */ BacktraceReport.prototype.isExceptionTypeReport = function () { return this.detectReportType(this.data); }; BacktraceReport.prototype.getPayload = function () { return this.data; }; /** * Set error or message in BacktraceReport object * @param err Current error */ BacktraceReport.prototype.setError = function (err) { this.data = err; if (this.detectReportType(err)) { this.err = err; this.classifiers = [err.name]; } else { this.err = new Error(err); this.classifiers = []; } }; /** * @deprecated * Please don't use log method in new BacktraceReport object. */ BacktraceReport.prototype.log = function () { console.warn('log method is deprecated.'); }; /** * @deprecated * Please don't use trace method in new BacktraceReport object */ BacktraceReport.prototype.trace = function () { console.warn('trace method is deprecated.'); }; /** * Add new attributes to existing report attributes * @param attributes new report attributes object */ BacktraceReport.prototype.addObjectAttributes = function (attributes) { this.clientAttributes = tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, this.clientAttributes), this.attributes), attributes); }; BacktraceReport.prototype.addAttribute = function (key, value) { this.clientAttributes[key] = value; }; BacktraceReport.prototype.addAnnotation = function (key, value) { this.annotations[key] = value; }; BacktraceReport.prototype.getAttachments = function () { return this.attachments; }; BacktraceReport.prototype.toJson = function () { return tslib_1.__awaiter(this, void 0, void 0, function () { var result; return tslib_1.__generator(this, function (_a) { switch (_a.label) { case 0: // why library should wait to retrieve source code data? // architecture decision require to pass additional parameters // not in constructor, but in additional method. return [4 /*yield*/, this.collectReportInformation()]; case 1: // why library should wait to retrieve source code data? // architecture decision require to pass additional parameters // not in constructor, but in additional method. _a.sent(); result = { uuid: this.uuid, timestamp: this.timestamp, lang: this.lang, langVersion: this.langVersion, mainThread: this.mainThread, classifiers: this.classifiers, threads: { main: this.stackTrace.toJson() }, agent: this.agent, agentVersion: this.agentVersion, annotations: this.annotations, attributes: this.attributes, sourceCode: this.stackTrace.getSourceCode(), symbolication_maps: this._symbolicationMap || this.stackTrace.symbolicationMaps, }; // when symbolication information exists, set symbolication to sourcemap. // we should check symbolicationMap and _symbolication boolean value and symbolication id from attributes // if any value exists, we should extend report object with 'sourcemap' property. if (this._symbolication || this.attributes['symbolication_id'] || this._symbolicationMap) { result.symbolication = 'sourcemap'; } return [2 /*return*/, result]; } }); }); }; BacktraceReport.prototype.setSourceCodeOptions = function (tabWidth, contextLineCount) { this.tabWidth = tabWidth; this.contextLineCount = contextLineCount; }; /** * Include symbolication information based on stack trace analysis */ BacktraceReport.prototype.includeSymbolication = function () { return this._symbolication && !this.attributes['symbolication_id'] && !this._symbolicationMap; }; BacktraceReport.prototype.collectReportInformation = function () { return tslib_1.__awaiter(this, void 0, void 0, function () { var _a; return tslib_1.__generator(this, function (_b) { switch (_b.label) { case 0: // get stack trace to retrieve calling module information this.stackTrace = new backtraceStackTrace_1.BacktraceStackTrace(this.err); this.stackTrace.setSourceCodeOptions(this.tabWidth, this.contextLineCount); return [4 /*yield*/, this.stackTrace.parseStackFrames(this.includeSymbolication())]; case 1: _b.sent(); // retrieve calling module object if (!this.attributes.hasOwnProperty('application')) { _a = moduleResolver_1.readModule(this.stackTrace.getCallingModulePath()), this._callingModule = _a[0], this._callingModulePath = _a[1]; } // combine attributes this.attributes = tslib_1.__assign(tslib_1.__assign({}, this.readBuiltInAttributes()), this.clientAttributes); // combine annotations this.annotations = this.readAnnotation(); return [2 /*return*/]; } }); }); }; BacktraceReport.prototype.readBuiltInAttributes = function () { return tslib_1.__assign(tslib_1.__assign(tslib_1.__assign(tslib_1.__assign({}, processHelper_1.readMemoryInformation()), processHelper_1.readProcessStatus()), this.readAttributes()), this.readErrorAttributes()); }; BacktraceReport.prototype.detectReportType = function (err) { return err instanceof Error; }; BacktraceReport.prototype.generateUuid = function () { var bytes = crypto_1.pseudoRandomBytes(16); return (bytes.slice(0, 4).toString('hex') + '-' + bytes.slice(4, 6).toString('hex') + '-' + bytes.slice(6, 8).toString('hex') + '-' + bytes.slice(8, 10).toString('hex') + '-' + bytes.slice(10, 16).toString('hex')); }; BacktraceReport.prototype.readErrorAttributes = function () { if (!this.detectReportType(this.err)) { return { 'error.message': this.err, }; } this.classifiers = [this.err.name]; return { 'error.message': this.err.message, }; }; BacktraceReport.prototype.readAttributes = function () { var result = moduleResolver_1.readSystemAttributes(); if (this._callingModule) { var _a = (this._callingModule || {}), name_1 = _a.name, version = _a.version, main = _a.main, description = _a.description, author = _a.author; result['name'] = name_1; result['version'] = version; result['main'] = main; result['description'] = description; result['author'] = typeof author === 'object' && author.name ? author.name : author; } return result; }; BacktraceReport.prototype.readAnnotation = function () { var result = { 'Environment Variables': process.env, 'Exec Arguments': process.execArgv, }; if (this.detectReportType(this.err)) { result['Exception'] = this.err; } return tslib_1.__assign(tslib_1.__assign({}, result), this.annotations); }; BacktraceReport.prototype.splitAttributesFromAnnotations = function (clientAttributes) { for (var key in clientAttributes) { if (clientAttributes.hasOwnProperty(key)) { var element = this.clientAttributes[key]; if (!element) { continue; } if (typeof element === 'object') { this.annotations[key] = element; } else { this.attributes[key] = element; } } } }; BacktraceReport.machineId = machineId_1.machineIdSync(true); return BacktraceReport; }()); exports.BacktraceReport = BacktraceReport; //# sourceMappingURL=backtraceReport.js.map