backtrace-node
Advanced tools
Comparing version 1.0.5 to 1.0.6-alpha.0
# Backtrace Node Release Notes | ||
## Version 1.0.6 30.10.2019 | ||
* Added sourcemap support to Backtrace-node | ||
* Fixed type attributes for report function | ||
* Changed a unit test result - removed console.log and check data instead. | ||
## Version 1.0.5 28.08.2019 | ||
@@ -4,0 +9,0 @@ * Fixed invalid source code line number |
@@ -16,6 +16,7 @@ "use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
@@ -22,0 +23,0 @@ }); |
@@ -14,2 +14,4 @@ /// <reference types="node" /> | ||
private _clientRateLimit; | ||
private _symbolication; | ||
private _symbolicationMap?; | ||
constructor(clientOptions: IBacktraceClientOptions | BacktraceClientOptions); | ||
@@ -25,2 +27,14 @@ /** | ||
/** | ||
* Set symbolication info | ||
*/ | ||
setSymbolication(): void; | ||
/** | ||
* Add symbolication map to each report. | ||
* @param symbolicationMap | ||
*/ | ||
setSymbolicationMap(symbolicationMap: Array<{ | ||
file: string; | ||
uuid: string; | ||
}>): void; | ||
/** | ||
* Clear all saved attributes | ||
@@ -27,0 +41,0 @@ */ |
@@ -27,6 +27,7 @@ "use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
@@ -77,6 +78,7 @@ }); | ||
_this._memorizedAttributes = {}; | ||
_this._symbolication = false; | ||
if (!clientOptions.endpoint) { | ||
throw new Error("Backtrace: missing 'endpoint' option."); | ||
} | ||
_this.options = __assign({}, new backtraceClientOptions_1.BacktraceClientOptions(), clientOptions); | ||
_this.options = __assign(__assign({}, new backtraceClientOptions_1.BacktraceClientOptions()), clientOptions); | ||
_this._backtraceApi = new backtraceApi_1.BacktraceApi(_this.getSubmitUrl(), _this.options.timeout); | ||
@@ -98,2 +100,25 @@ _this._clientRateLimit = new clientRateLimit_1.ClientRateLimit(_this.options.rateLimit); | ||
/** | ||
* Set symbolication info | ||
*/ | ||
BacktraceClient.prototype.setSymbolication = function () { | ||
this._symbolication = true; | ||
}; | ||
/** | ||
* Add symbolication map to each report. | ||
* @param symbolicationMap | ||
*/ | ||
BacktraceClient.prototype.setSymbolicationMap = function (symbolicationMap) { | ||
if (!symbolicationMap) { | ||
throw new Error('Symbolication map is undefined'); | ||
} | ||
if (!Array.isArray(symbolicationMap)) { | ||
throw new TypeError('Invalid type of symbolication map'); | ||
} | ||
var invalidValues = symbolicationMap.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 = symbolicationMap; | ||
}; | ||
/** | ||
* Clear all saved attributes | ||
@@ -116,2 +141,6 @@ */ | ||
var report = new backtraceReport_1.BacktraceReport(payload, attributes, fileAttachments); | ||
report.symbolication = this._symbolication; | ||
if (this._symbolicationMap) { | ||
report.symbolicationMap = this._symbolicationMap; | ||
} | ||
report.setSourceCodeOptions(this.options.tabWidth, this.options.contextLineCount); | ||
@@ -231,3 +260,3 @@ return report; | ||
} | ||
return __assign({}, attributes, this.options.attributes, this.getMemorizedAttributes()); | ||
return __assign(__assign(__assign({}, attributes), this.options.attributes), this.getMemorizedAttributes()); | ||
}; | ||
@@ -234,0 +263,0 @@ BacktraceClient.prototype.getMemorizedAttributes = function () { |
@@ -25,3 +25,3 @@ import { BacktraceClient } from './backtraceClient'; | ||
*/ | ||
export declare function report(arg: () => void | Error | string | object, arg2?: object | undefined, arg3?: string[] | ((data?: Error) => void), arg4?: string[]): Promise<BacktraceResult>; | ||
export declare function report(arg: Error | string | object | ((data?: Error) => void), arg2?: object | undefined, arg3?: string[] | ((data?: Error) => void), arg4?: string[]): Promise<BacktraceResult>; | ||
/** | ||
@@ -28,0 +28,0 @@ * Send report synchronosuly to Backtrace |
@@ -14,6 +14,7 @@ "use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
@@ -162,3 +163,3 @@ }); | ||
} | ||
backtraceClient.reportSync(err, __assign({}, req, resp)); | ||
backtraceClient.reportSync(err, __assign(__assign({}, req), resp)); | ||
next(err); | ||
@@ -165,0 +166,0 @@ } |
@@ -7,2 +7,3 @@ import { ISourceCode } from './sourceCode'; | ||
langVersion: string; | ||
symbolication?: 'sourcemap'; | ||
agent: string; | ||
@@ -22,2 +23,6 @@ agentVersion: string; | ||
}; | ||
symbolication_maps?: Array<{ | ||
file: string; | ||
uuid: string; | ||
}>; | ||
} |
@@ -10,2 +10,7 @@ import { IBacktraceData } from './backtraceData'; | ||
private attachments; | ||
set symbolication(symbolication: boolean); | ||
set symbolicationMap(symbolMap: Array<{ | ||
file: string; | ||
uuid: string; | ||
}>); | ||
readonly uuid: string; | ||
@@ -37,2 +42,4 @@ readonly timestamp: number; | ||
stackTrace: BacktraceStackTrace; | ||
private _symbolicationMap?; | ||
private _symbolication; | ||
/** | ||
@@ -101,2 +108,6 @@ * Current report attributes | ||
setSourceCodeOptions(tabWidth: number, contextLineCount: number): void; | ||
/** | ||
* Include symbolication information based on stack trace analysis | ||
*/ | ||
private includeSymbolication; | ||
private collectReportInformation; | ||
@@ -103,0 +114,0 @@ private readBuiltInAttributes; |
@@ -14,6 +14,7 @@ "use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
@@ -103,2 +104,3 @@ }); | ||
this.classifiers = []; | ||
this._symbolication = false; | ||
/** | ||
@@ -123,2 +125,26 @@ * Current report attributes | ||
} | ||
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 | ||
}); | ||
/** | ||
@@ -167,3 +193,3 @@ * Check if report contains exception information | ||
BacktraceReport.prototype.addObjectAttributes = function (attributes) { | ||
this.clientAttributes = __assign({}, this.clientAttributes, this.attributes, attributes); | ||
this.clientAttributes = __assign(__assign(__assign({}, this.clientAttributes), this.attributes), attributes); | ||
}; | ||
@@ -181,2 +207,3 @@ BacktraceReport.prototype.addAttribute = function (key, value) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var result; | ||
return __generator(this, function (_a) { | ||
@@ -194,16 +221,24 @@ switch (_a.label) { | ||
_a.sent(); | ||
return [2 /*return*/, { | ||
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(), | ||
}]; | ||
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]; | ||
} | ||
@@ -217,2 +252,8 @@ }); | ||
}; | ||
/** | ||
* 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 () { | ||
@@ -227,3 +268,3 @@ return __awaiter(this, void 0, void 0, function () { | ||
this.stackTrace.setSourceCodeOptions(this.tabWidth, this.contextLineCount); | ||
return [4 /*yield*/, this.stackTrace.parseStackFrames()]; | ||
return [4 /*yield*/, this.stackTrace.parseStackFrames(this.includeSymbolication())]; | ||
case 1: | ||
@@ -234,3 +275,3 @@ _b.sent(); | ||
// combine attributes | ||
this.attributes = __assign({}, this.readBuiltInAttributes(), this.clientAttributes); | ||
this.attributes = __assign(__assign({}, this.readBuiltInAttributes()), this.clientAttributes); | ||
// combine annotations | ||
@@ -244,3 +285,3 @@ this.annotations = this.readAnnotation(); | ||
BacktraceReport.prototype.readBuiltInAttributes = function () { | ||
return __assign({}, processHelper_1.readMemoryInformation(), processHelper_1.readProcessStatus(), this.readAttributes(), this.readErrorAttributes()); | ||
return __assign(__assign(__assign(__assign({}, processHelper_1.readMemoryInformation()), processHelper_1.readProcessStatus()), this.readAttributes()), this.readErrorAttributes()); | ||
}; | ||
@@ -311,3 +352,3 @@ BacktraceReport.prototype.detectReportType = function (err) { | ||
} | ||
return __assign({}, result, this.annotations); | ||
return __assign(__assign({}, result), this.annotations); | ||
}; | ||
@@ -314,0 +355,0 @@ BacktraceReport.prototype.splitAttributesFromAnnotations = function (clientAttributes) { |
@@ -50,8 +50,8 @@ import { BacktraceReport } from './backtraceReport'; | ||
private readonly _rxId; | ||
readonly ObjectId: string; | ||
readonly Report: BacktraceReport; | ||
readonly Message: string; | ||
readonly Error: Error | undefined; | ||
readonly Status: BacktraceResultStatus; | ||
get ObjectId(): string; | ||
get Report(): BacktraceReport; | ||
get Message(): string; | ||
get Error(): Error | undefined; | ||
get Status(): BacktraceResultStatus; | ||
private constructor(); | ||
} |
@@ -24,2 +24,7 @@ import { ISourceCode } from './sourceCode'; | ||
}; | ||
symbolicationMaps?: Array<{ | ||
file: string; | ||
uuid: string; | ||
}>; | ||
private symbolicationPaths; | ||
private callingModulePath; | ||
@@ -53,3 +58,5 @@ private readonly stackLineRe; | ||
*/ | ||
parseStackFrames(): Promise<void>; | ||
parseStackFrames(includeSymbolication: boolean): Promise<void>; | ||
private generateSymbolicationMap; | ||
private convertHexToUuid; | ||
private addSourceRequest; | ||
@@ -56,0 +63,0 @@ private readSourceCode; |
"use strict"; | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
@@ -45,2 +46,3 @@ }); | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var crypto_1 = require("crypto"); | ||
var fs = __importStar(require("fs")); | ||
@@ -60,2 +62,3 @@ var path_1 = require("path"); | ||
this.sourceCodeInformation = {}; | ||
this.symbolicationPaths = new Set(); | ||
this.callingModulePath = ''; | ||
@@ -103,3 +106,3 @@ this.stackLineRe = /\s+at (.+) \((.+):(\d+):(\d+)\)/; | ||
*/ | ||
BacktraceStackTrace.prototype.parseStackFrames = function () { | ||
BacktraceStackTrace.prototype.parseStackFrames = function (includeSymbolication) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
@@ -133,3 +136,10 @@ var stackTrace, lines, backtracePath; | ||
}; | ||
_this.addSourceRequest(stackFrame); | ||
// ignore not existing stack frames | ||
if (fs.existsSync(stackFrame.sourceCode)) { | ||
_this.addSourceRequest(stackFrame); | ||
// extend root object with symbolication information | ||
if (includeSymbolication) { | ||
_this.symbolicationPaths.add(stackFrame.sourceCode); | ||
} | ||
} | ||
if (_this.isCallingModule(stackFrame)) { | ||
@@ -145,2 +155,5 @@ _this.callingModulePath = stackFrame.sourceCode; | ||
_a.sent(); | ||
if (includeSymbolication) { | ||
this.generateSymbolicationMap(); | ||
} | ||
return [2 /*return*/]; | ||
@@ -151,7 +164,36 @@ } | ||
}; | ||
BacktraceStackTrace.prototype.addSourceRequest = function (stackFrame) { | ||
// ignore not existing stack frames | ||
if (!fs.existsSync(stackFrame.sourceCode)) { | ||
BacktraceStackTrace.prototype.generateSymbolicationMap = function () { | ||
var _this = this; | ||
if (this.symbolicationPaths.size === 0) { | ||
return; | ||
} | ||
this.symbolicationMaps = []; | ||
this.symbolicationPaths.forEach(function (symbolicationPath) { return __awaiter(_this, void 0, void 0, function () { | ||
var file, hash; | ||
var _a; | ||
return __generator(this, function (_b) { | ||
file = fs.readFileSync(symbolicationPath, 'utf8'); | ||
hash = crypto_1.createHash('md5') | ||
.update(file) | ||
.digest('hex'); | ||
(_a = this.symbolicationMaps) === null || _a === void 0 ? void 0 : _a.push({ | ||
file: symbolicationPath, | ||
uuid: this.convertHexToUuid(hash), | ||
}); | ||
return [2 /*return*/]; | ||
}); | ||
}); }); | ||
}; | ||
BacktraceStackTrace.prototype.convertHexToUuid = function (hex) { | ||
return (hex.slice(0, 8) + | ||
'-' + | ||
hex.slice(8, 12) + | ||
'-' + | ||
hex.slice(12, 16) + | ||
'-' + | ||
hex.slice(16, 20) + | ||
'-' + | ||
hex.slice(20, 32)); | ||
}; | ||
BacktraceStackTrace.prototype.addSourceRequest = function (stackFrame) { | ||
// add source code to existing list. Otherwise create empty array | ||
@@ -158,0 +200,0 @@ this.requestedSourceCode[stackFrame.sourceCode] = this.requestedSourceCode[stackFrame.sourceCode] || []; |
{ | ||
"name": "backtrace-node", | ||
"version": "1.0.5", | ||
"version": "1.0.6-alpha.0", | ||
"description": "Backtrace error reporting tool", | ||
@@ -52,4 +52,4 @@ "main": "./lib/index.js", | ||
"tslint-config-prettier": "^1.18.0", | ||
"typescript": "^3.3.4000" | ||
"typescript": "^3.7.4" | ||
} | ||
} |
@@ -17,2 +17,4 @@ import { ClientRateLimit } from './clientRateLimit'; | ||
private _clientRateLimit: ClientRateLimit; | ||
private _symbolication = false; | ||
private _symbolicationMap?: Array<{ file: string; uuid: string }>; | ||
@@ -45,2 +47,29 @@ constructor(clientOptions: IBacktraceClientOptions | BacktraceClientOptions) { | ||
/** | ||
* Set symbolication info | ||
*/ | ||
public setSymbolication() { | ||
this._symbolication = true; | ||
} | ||
/** | ||
* Add symbolication map to each report. | ||
* @param symbolicationMap | ||
*/ | ||
public setSymbolicationMap(symbolicationMap: Array<{ file: string; uuid: string }>) { | ||
if (!symbolicationMap) { | ||
throw new Error('Symbolication map is undefined'); | ||
} | ||
if (!Array.isArray(symbolicationMap)) { | ||
throw new TypeError('Invalid type of symbolication map'); | ||
} | ||
const invalidValues = symbolicationMap.some((n) => !n.file || !n.uuid); | ||
if (invalidValues) { | ||
throw new TypeError('Symbolication map contains invalid values - missing file or uuid value'); | ||
} | ||
this._symbolicationMap = symbolicationMap; | ||
} | ||
/** | ||
* Clear all saved attributes | ||
@@ -67,2 +96,6 @@ */ | ||
const report = new BacktraceReport(payload, attributes, fileAttachments); | ||
report.symbolication = this._symbolication; | ||
if (this._symbolicationMap) { | ||
report.symbolicationMap = this._symbolicationMap; | ||
} | ||
report.setSourceCodeOptions(this.options.tabWidth, this.options.contextLineCount); | ||
@@ -69,0 +102,0 @@ return report; |
@@ -38,3 +38,3 @@ import { BacktraceClient } from './backtraceClient'; | ||
export async function report( | ||
arg: () => void | Error | string | object, | ||
arg: Error | string | object | ((data?: Error) => void), | ||
arg2: object | undefined = {}, | ||
@@ -41,0 +41,0 @@ // tslint:disable-next-line: ban-types |
@@ -8,2 +8,3 @@ import { ISourceCode } from './sourceCode'; | ||
langVersion: string; | ||
symbolication?: 'sourcemap'; | ||
agent: string; | ||
@@ -17,2 +18,3 @@ agentVersion: string; | ||
sourceCode: { [index: string]: ISourceCode }; | ||
symbolication_maps?: Array<{ file: string; uuid: string }>; | ||
} |
@@ -15,2 +15,21 @@ // tslint:disable-next-line: no-var-requires | ||
export class BacktraceReport { | ||
public set symbolication(symbolication: boolean) { | ||
this._symbolication = symbolication; | ||
} | ||
public set symbolicationMap(symbolMap: Array<{ file: string; uuid: string }>) { | ||
if (!symbolMap) { | ||
throw new Error('Symbolication map is undefined'); | ||
} | ||
if (!Array.isArray(symbolMap)) { | ||
throw new TypeError('Invalid type of symbolication map'); | ||
} | ||
const invalidValues = symbolMap.some((n) => !n.file || !n.uuid); | ||
if (invalidValues) { | ||
throw new TypeError('Symbolication map contains invalid values - missing file or uuid value'); | ||
} | ||
this._symbolicationMap = symbolMap; | ||
} | ||
// reprot id | ||
@@ -54,2 +73,6 @@ public readonly uuid: string = this.generateUuid(); | ||
private _symbolicationMap?: Array<{ file: string; uuid: string }>; | ||
private _symbolication = false; | ||
/** | ||
@@ -173,3 +196,3 @@ * Current report attributes | ||
return { | ||
const result = { | ||
uuid: this.uuid, | ||
@@ -187,3 +210,12 @@ timestamp: this.timestamp, | ||
sourceCode: this.stackTrace.getSourceCode(), | ||
}; | ||
symbolication_maps: this._symbolicationMap || this.stackTrace.symbolicationMaps, | ||
} as IBacktraceData; | ||
// 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 result; | ||
} | ||
@@ -196,2 +228,9 @@ | ||
/** | ||
* Include symbolication information based on stack trace analysis | ||
*/ | ||
private includeSymbolication(): boolean { | ||
return this._symbolication && !this.attributes['symbolication_id'] && !this._symbolicationMap; | ||
} | ||
private async collectReportInformation(): Promise<void> { | ||
@@ -201,3 +240,3 @@ // get stack trace to retrieve calling module information | ||
this.stackTrace.setSourceCodeOptions(this.tabWidth, this.contextLineCount); | ||
await this.stackTrace.parseStackFrames(); | ||
await this.stackTrace.parseStackFrames(this.includeSymbolication()); | ||
// retrieve calling module object | ||
@@ -204,0 +243,0 @@ [this._callingModule, this._callingModulePath] = readModule(this.stackTrace.getCallingModulePath()); |
@@ -0,4 +1,6 @@ | ||
import { createHash } from 'crypto'; | ||
import * as fs from 'fs'; | ||
import { join } from 'path'; | ||
import { scanFile } from 'source-scan'; | ||
import { promisify } from 'util'; | ||
import { ISourceCode, ISourceLocation, ISourceScan } from './sourceCode'; | ||
@@ -27,2 +29,5 @@ | ||
public sourceCodeInformation: { [index: string]: ISourceCode } = {}; | ||
public symbolicationMaps?: Array<{ file: string; uuid: string }>; | ||
private symbolicationPaths = new Set<string>(); | ||
private callingModulePath = ''; | ||
@@ -77,3 +82,3 @@ private readonly stackLineRe = /\s+at (.+) \((.+):(\d+):(\d+)\)/; | ||
*/ | ||
public async parseStackFrames(): Promise<void> { | ||
public async parseStackFrames(includeSymbolication: boolean): Promise<void> { | ||
const stackTrace = this.error.stack; | ||
@@ -104,3 +109,11 @@ if (!stackTrace) { | ||
this.addSourceRequest(stackFrame); | ||
// ignore not existing stack frames | ||
if (fs.existsSync(stackFrame.sourceCode)) { | ||
this.addSourceRequest(stackFrame); | ||
// extend root object with symbolication information | ||
if (includeSymbolication) { | ||
this.symbolicationPaths.add(stackFrame.sourceCode); | ||
} | ||
} | ||
if (this.isCallingModule(stackFrame)) { | ||
@@ -114,9 +127,39 @@ this.callingModulePath = stackFrame.sourceCode; | ||
await this.readSourceCode(); | ||
if (includeSymbolication) { | ||
this.generateSymbolicationMap(); | ||
} | ||
} | ||
private generateSymbolicationMap(): void { | ||
if (this.symbolicationPaths.size === 0) { | ||
return; | ||
} | ||
this.symbolicationMaps = []; | ||
this.symbolicationPaths.forEach(async (symbolicationPath) => { | ||
const file = fs.readFileSync(symbolicationPath, 'utf8'); | ||
const hash = createHash('md5') | ||
.update(file) | ||
.digest('hex'); | ||
this.symbolicationMaps?.push({ | ||
file: symbolicationPath, | ||
uuid: this.convertHexToUuid(hash), | ||
}); | ||
}); | ||
} | ||
private convertHexToUuid(hex: string): string { | ||
return ( | ||
hex.slice(0, 8) + | ||
'-' + | ||
hex.slice(8, 12) + | ||
'-' + | ||
hex.slice(12, 16) + | ||
'-' + | ||
hex.slice(16, 20) + | ||
'-' + | ||
hex.slice(20, 32) | ||
); | ||
} | ||
private addSourceRequest(stackFrame: IBacktraceStackFrame): void { | ||
// ignore not existing stack frames | ||
if (!fs.existsSync(stackFrame.sourceCode)) { | ||
return; | ||
} | ||
// add source code to existing list. Otherwise create empty array | ||
@@ -123,0 +166,0 @@ this.requestedSourceCode[stackFrame.sourceCode] = this.requestedSourceCode[stackFrame.sourceCode] || []; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
176116
3306
8
53
2