diff --git a/__tests__/stackconverter.test.ts b/__tests__/stack-converter.test.ts similarity index 86% rename from __tests__/stackconverter.test.ts rename to __tests__/stack-converter.test.ts index e6cf561..aaaadb4 100644 --- a/__tests__/stackconverter.test.ts +++ b/__tests__/stack-converter.test.ts @@ -1,6 +1,6 @@ import * as fs from "fs"; import * as path from "path"; -import { StackConverter } from "../src/stackconverter"; +import { StackConverter } from "../lib/stack-converter"; const TESTING_DIR = "__tests__"; const TESTING_DATA_DIR = path.join(TESTING_DIR, "test-data"); @@ -50,20 +50,22 @@ describe("StackConverter", () => { test("source map file that does not exist results stack frame with error message", async () => { const missingJsFileName = "does-not-exist.js"; - const missingJsMapPath = path.join(TESTING_DATA_DIR, `${missingJsFileName}.map`); + const missingJsMapFileName = `${missingJsFileName}.map` + const missingJsMapPath = path.join(TESTING_DATA_DIR, missingJsMapFileName); const stackConverter = new StackConverter([missingJsMapPath]); const { error, stack } = await stackConverter.convert(` at hello (${missingJsFileName}:1:1337)`); expect(error).toBeFalsy(); - expect(stack).toMatch(new RegExp(`Error loading source map for frame \\(file ${missingJsMapPath} does not exist or is inaccessible\\)`)); + expect(stack).toMatch(new RegExp(`Error loading source map for frame \\(file .*${missingJsMapFileName} does not exist or is inaccessible\\)`)); }); test("empty source map file results stack frame with error message", async () => { const emptyJsFileName = "empty.js"; - const emptyJsMapPath = path.join(TESTING_DATA_DIR, `${emptyJsFileName}.map`); + const emptyJsMapFileName = `${emptyJsFileName}.map` + const emptyJsMapPath = path.join(TESTING_DATA_DIR, emptyJsMapFileName); const stackConverter = new StackConverter([emptyJsMapPath]); const { error, stack } = await stackConverter.convert(` at hello (${emptyJsFileName}:1:1337)`); expect(error).toBeFalsy(); - expect(stack).toMatch(new RegExp(`Error loading source map for frame \\(file ${emptyJsMapPath} was empty\\)`)); + expect(stack).toMatch(new RegExp(`Error loading source map for frame \\(file .*${emptyJsMapFileName} was empty\\)`)); }); test("source map file that can't be parsed results stack frame with error message", async () => { @@ -84,7 +86,8 @@ describe("StackConverter", () => { const { error, stack } = await stackConverter.convert(stackText); expect(error).toBeUndefined(); expect(stack).toMatchInlineSnapshot(` - " at (dummy.ts:2:31) + "Error: Crush your bugs! + at (dummy.ts:2:31) at (dummy.ts:2:31) at (dummy.ts:2:31) at (dummy.ts:2:31) @@ -109,7 +112,8 @@ describe("StackConverter", () => { expect(error).toBeUndefined(); expect(stackText).toEqual(stackText); expect(stack).toMatchInlineSnapshot(` - " at (webpack:///src/app/common/services/bugsplat-custom-error-handler/bugsplat-custom-error-handler.ts:32:16) + "Error: Http failure response for https://app.bugsplat.com/api/subscription.php?database=AutoDb_04102021_95345: 502 OK + at (webpack:///src/app/common/services/bugsplat-custom-error-handler/bugsplat-custom-error-handler.ts:32:16) at Generator.next () at next (webpack:///node_modules/tslib/tslib.es6.js:74:70) at executor (webpack:///node_modules/zone.js/dist/zone-evergreen.js:960:32) @@ -131,7 +135,8 @@ describe("StackConverter", () => { expect(error).toBeUndefined(); expect(stackText).toEqual(stackText); expect(stack).toMatchInlineSnapshot(` - " at (webpack:///src/app/common/services/bugsplat-custom-error-handler/bugsplat-custom-error-handler.ts:32:16) + "Error: Http failure response for https://app.bugsplat.com/api/subscription.php?database=AutoDb_04102021_95345: 502 OK + at (webpack:///src/app/common/services/bugsplat-custom-error-handler/bugsplat-custom-error-handler.ts:32:16) at Generator.next () at next (webpack:///node_modules/tslib/tslib.es6.js:74:70) at executor (webpack:///node_modules/zone.js/dist/zone-evergreen.js:960:32) diff --git a/lib/stack-converter.ts b/lib/stack-converter.ts index d055340..ce8f170 100644 --- a/lib/stack-converter.ts +++ b/lib/stack-converter.ts @@ -63,6 +63,11 @@ export class StackConverter { const sourceMaps: { [filename: string]: SourceMapConsumer } = {}; const sourceMapErrors: { [filename: string]: boolean } = {}; + const errorLine = StackConverter.getChromiumErrorLineOrEmpty(stack); + if (errorLine) { + buff.push(errorLine); + } + for (const frame of stackFrames) { const { file, methodName, lineNumber, column } = frame; if (file in sourceMapErrors) { @@ -138,6 +143,15 @@ export class StackConverter { return `${StackConverter.INDENT}at ${method} (${file}:${line}:${column})` + (comment ? ' ***' + comment : ''); } + private static getChromiumErrorLineOrEmpty(stack: string): string { + const parts = stack.split('\n'); + if (parts[0].startsWith('Error:')) { + return parts[0]; + } + + return ''; + } + private static async sourceMapFromFile(file: string): Promise<{sourceMap?: SourceMapConsumer, error?: string}> { if (!file) { return { error: 'file name was empty' };