diff --git a/test/vendor/fixtures/captured-errors.js b/test/vendor/fixtures/captured-errors.js index b75dcc0c599c..3efdf6ad091d 100644 --- a/test/vendor/fixtures/captured-errors.js +++ b/test/vendor/fixtures/captured-errors.js @@ -309,7 +309,7 @@ CapturedExceptions.FIREFOX_MOZ_EXTENSION = { stack: 'render@moz-extension://path/data/content/bundle.js:5529:16\n' + 'dispatchEvent@moz-extension://path/data/content/vendor.bundle.js:18:23028\n' + - 'wrapped@moz-extension//path/data/content/bundle.js:7270:25', + 'wrapped@moz-extension://path/data/content/bundle.js:7270:25', fileName: 'moz-extension://path/data/content/bundle.js', lineNumber: 5529, columnNumber: 16, @@ -504,4 +504,10 @@ CapturedExceptions.CHROME_ELECTRON = { ' at TESTTESTTEST.someMethod (C:\\Users\\user\\path\\to\\file.js:295:108)' }; +CapturedExceptions.CUSTOM_ERROR = { + message: 'test', + name: 'HttpError', + stack: 'HttpError: test\n' + ' at file:///path/to/file.js:19:40' +}; + module.exports = CapturedExceptions; diff --git a/test/vendor/tracekit-parser.test.js b/test/vendor/tracekit-parser.test.js index 4943a03afecb..47924cfbf5e7 100644 --- a/test/vendor/tracekit-parser.test.js +++ b/test/vendor/tracekit-parser.test.js @@ -881,5 +881,18 @@ describe('TraceKit', function() { column: 108 }); }); + + it('should parse custom errors', function() { + var stackFrames = TraceKit.computeStackTrace(CapturedExceptions.CUSTOM_ERROR); + assert.ok(stackFrames); + assert.deepEqual(stackFrames.stack.length, 1); + assert.deepEqual(stackFrames.stack[0], { + url: 'file:///path/to/file.js', + func: '?', + args: [], + line: 19, + column: 40 + }); + }); }); }); diff --git a/vendor/TraceKit/tracekit.js b/vendor/TraceKit/tracekit.js index 3c92edd6fa39..2a313fe5b988 100644 --- a/vendor/TraceKit/tracekit.js +++ b/vendor/TraceKit/tracekit.js @@ -372,18 +372,20 @@ TraceKit.computeStackTrace = (function computeStackTraceWrapper() { function computeStackTraceFromStackProp(ex) { if (typeof ex.stack === 'undefined' || !ex.stack) return; - var chrome = /^\s*at (?:(.*?) ?\()?((?:file|https?|blob|chrome-extension|native|eval|webpack||[a-z]:|\/).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i, - gecko = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)((?:file|https?|blob|chrome|webpack|resource|moz-extension|\[native).*?|[^@]*bundle)(?::(\d+))?(?::(\d+))?\s*$/i, - winjs = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx(?:-web)|https?|webpack|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i, - // Used to additionally parse URL/line/column from eval frames - geckoEval = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i, - chromeEval = /\((\S*)(?::(\d+))(?::(\d+))\)/, - lines = ex.stack.split('\n'), - stack = [], - submatch, - parts, - element, - reference = /^(.*) is undefined$/.exec(ex.message); + var chrome = /^\s*at (?:(.*?) ?\()?((?:file|https?|blob|chrome-extension|native|eval|webpack||[a-z]:|\/).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i; + var winjs = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx(?:-web)|https?|webpack|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i; + // NOTE: blob urls are now supposed to always have an origin, therefore it's format + // which is `blob:http://url/path/with-some-uuid`, is matched by `blob.*?:\/` as well + var gecko = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)((?:file|https?|blob|chrome|webpack|resource|moz-extension).*?:\/.*?|\[native code\]|[^@]*bundle)(?::(\d+))?(?::(\d+))?\s*$/i; + // Used to additionally parse URL/line/column from eval frames + var geckoEval = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i; + var chromeEval = /\((\S*)(?::(\d+))(?::(\d+))\)/; + var lines = ex.stack.split('\n'); + var stack = []; + var submatch; + var parts; + var element; + var reference = /^(.*) is undefined$/.exec(ex.message); for (var i = 0, j = lines.length; i < j; ++i) { if ((parts = chrome.exec(lines[i]))) {