Skip to content

Commit 80ac1f8

Browse files
committed
Merge pull request #440 from getsentry/rebase-tracekit
Manually rebase with latest csnover/TraceKit ...
2 parents 70f07ed + e7a74e1 commit 80ac1f8

File tree

2 files changed

+80
-47
lines changed

2 files changed

+80
-47
lines changed

test/vendor/tracekit.test.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,20 @@ describe('TraceKit', function(){
2929
assert.equal(trace.stack[4].func, '?');
3030
assert.equal(trace.stack[5].func, 'namedFunc4');
3131
});
32+
33+
it('should handle eval/anonymous strings in Chrome 46', function () {
34+
var stack_str = "" +
35+
"ReferenceError: baz is not defined\n" +
36+
" at bar (http://example.com/js/test.js:19:7)\n" +
37+
" at foo (http://example.com/js/test.js:23:7)\n" +
38+
" at eval (eval at <anonymous> (http://example.com/js/test.js:26:5), <anonymous>:1:26)\n";
39+
40+
var mock_err = { stack: stack_str };
41+
var trace = TraceKit.computeStackTrace.computeStackTraceFromStackProp(mock_err);
42+
assert.equal(trace.stack[0].func, 'bar');
43+
assert.equal(trace.stack[1].func, 'foo');
44+
assert.equal(trace.stack[2].func, 'eval');
45+
});
3246
});
3347

3448
describe('.computeStackTrace', function() {

vendor/TraceKit/tracekit.js

Lines changed: 66 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -615,37 +615,40 @@ TraceKit.computeStackTrace = (function computeStackTraceWrapper() {
615615
function computeStackTraceFromStackProp(ex) {
616616
if (isUndefined(ex.stack) || !ex.stack) return;
617617

618-
var chrome = /^\s*at (.*?) ?\(?((?:(?:file|https?|chrome-extension):.*?)|<anonymous>):(\d+)(?::(\d+))?\)?\s*$/i,
619-
gecko = /^\s*(.*?)(?:\((.*?)\))?@((?:file|https?|chrome).*?):(\d+)(?::(\d+))?\s*$/i,
620-
winjs = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:ms-appx|http|https):.*?):(\d+)(?::(\d+))?\)?\s*$/i,
618+
var chrome = /^\s*at (.*?) ?\((((?:file|https?|blob|chrome-extension|native|eval).*?)|<anonymous>)(?::(\d+))?(?::(\d+))?\)?\s*$/i,
619+
gecko = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)((?:file|https?|blob|chrome|\[).*?)(?::(\d+))?(?::(\d+))?\s*$/i,
620+
winjs = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:ms-appx|https?|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i,
621621
lines = ex.stack.split('\n'),
622622
stack = [],
623623
parts,
624624
element,
625625
reference = /^(.*) is undefined$/.exec(ex.message);
626626

627627
for (var i = 0, j = lines.length; i < j; ++i) {
628-
if ((parts = gecko.exec(lines[i]))) {
628+
if ((parts = chrome.exec(lines[i]))) {
629+
var isNative = parts[2] && parts[2].indexOf('native') !== -1;
629630
element = {
630-
'url': parts[3],
631+
'url': !isNative ? parts[2] : null,
631632
'func': parts[1] || UNKNOWN_FUNCTION,
632-
'args': parts[2] ? parts[2].split(',') : '',
633-
'line': +parts[4],
634-
'column': parts[5] ? +parts[5] : null
633+
'args': isNative ? [parts[2]] : [],
634+
'line': parts[3] ? +parts[3] : null,
635+
'column': parts[4] ? +parts[4] : null
635636
};
636-
} else if ((parts = chrome.exec(lines[i]))) {
637+
} else if ( parts = winjs.exec(lines[i]) ) {
637638
element = {
638639
'url': parts[2],
639640
'func': parts[1] || UNKNOWN_FUNCTION,
641+
'args': [],
640642
'line': +parts[3],
641643
'column': parts[4] ? +parts[4] : null
642644
};
643-
} else if ((parts = winjs.exec(lines[i]))) {
645+
} else if ((parts = gecko.exec(lines[i]))) {
644646
element = {
645-
'url': parts[2],
647+
'url': parts[3],
646648
'func': parts[1] || UNKNOWN_FUNCTION,
647-
'line': +parts[3],
648-
'column': parts[4] ? +parts[4] : null
649+
'args': parts[2] ? parts[2].split(',') : [],
650+
'line': parts[4] ? +parts[4] : null,
651+
'column': parts[5] ? +parts[5] : null
649652
};
650653
} else {
651654
continue;
@@ -696,21 +699,33 @@ TraceKit.computeStackTrace = (function computeStackTraceWrapper() {
696699
var stacktrace = ex.stacktrace;
697700
if (isUndefined(ex.stacktrace) || !ex.stacktrace) return;
698701

699-
var testRE = / line (\d+), column (\d+) in (?:<anonymous function: ([^>]+)>|([^\)]+))\((.*)\) in (.*):\s*$/i,
700-
lines = stacktrace.split('\n'),
701-
stack = [],
702-
parts;
702+
var opera10Regex = / line (\d+).*script (?:in )?(\S+)(?:: in function (\S+))?$/i,
703+
opera11Regex = / line (\d+), column (\d+)\s*(?:in (?:<anonymous function: ([^>]+)>|([^\)]+))\((.*)\))? in (.*):\s*$/i,
704+
lines = stacktrace.split('\n'),
705+
stack = [],
706+
parts;
703707

704-
for (var i = 0, j = lines.length; i < j; i += 2) {
705-
if ((parts = testRE.exec(lines[i]))) {
706-
var element = {
708+
for (var line = 0; line < lines.length; line += 2) {
709+
var element = null;
710+
if ((parts = opera10Regex.exec(lines[line]))) {
711+
element = {
712+
'url': parts[2],
713+
'line': +parts[1],
714+
'column': null,
715+
'func': parts[3],
716+
'args':[]
717+
};
718+
} else if ((parts = opera11Regex.exec(lines[line]))) {
719+
element = {
720+
'url': parts[6],
707721
'line': +parts[1],
708722
'column': +parts[2],
709723
'func': parts[3] || parts[4],
710-
'args': parts[5] ? parts[5].split(',') : [],
711-
'url': parts[6]
724+
'args': parts[5] ? parts[5].split(',') : []
712725
};
726+
}
713727

728+
if (element) {
714729
if (!element.func && element.line) {
715730
element.func = guessFunctionName(element.url, element.line);
716731
}
@@ -721,7 +736,7 @@ TraceKit.computeStackTrace = (function computeStackTraceWrapper() {
721736
}
722737

723738
if (!element.context) {
724-
element.context = [lines[i + 1]];
739+
element.context = [lines[line + 1]];
725740
}
726741

727742
stack.push(element);
@@ -769,40 +784,42 @@ TraceKit.computeStackTrace = (function computeStackTraceWrapper() {
769784
return null;
770785
}
771786

772-
var lineRE1 = /^\s*Line (\d+) of linked script ((?:file|https?)\S+)(?:: in function (\S+))?\s*$/i,
773-
lineRE2 = /^\s*Line (\d+) of inline#(\d+) script in ((?:file|https?)\S+)(?:: in function (\S+))?\s*$/i,
787+
var lineRE1 = /^\s*Line (\d+) of linked script ((?:file|https?|blob)\S+)(?:: in function (\S+))?\s*$/i,
788+
lineRE2 = /^\s*Line (\d+) of inline#(\d+) script in ((?:file|https?|blob)\S+)(?:: in function (\S+))?\s*$/i,
774789
lineRE3 = /^\s*Line (\d+) of function script\s*$/i,
775790
stack = [],
776791
scripts = document.getElementsByTagName('script'),
777792
inlineScriptBlocks = [],
778-
parts,
779-
i,
780-
len,
781-
source;
793+
parts;
782794

783-
for (i in scripts) {
784-
if (hasKey(scripts, i) && !scripts[i].src) {
785-
inlineScriptBlocks.push(scripts[i]);
795+
for (var s in scripts) {
796+
if (hasKey(scripts, s) && !scripts[s].src) {
797+
inlineScriptBlocks.push(scripts[s]);
786798
}
787799
}
788800

789-
for (i = 2, len = lines.length; i < len; i += 2) {
801+
for (var line = 2; line < lines.length; line += 2) {
790802
var item = null;
791-
if ((parts = lineRE1.exec(lines[i]))) {
803+
if ((parts = lineRE1.exec(lines[line]))) {
792804
item = {
793805
'url': parts[2],
794806
'func': parts[3],
795-
'line': +parts[1]
807+
'args': [],
808+
'line': +parts[1],
809+
'column': null
796810
};
797-
} else if ((parts = lineRE2.exec(lines[i]))) {
811+
} else if ((parts = lineRE2.exec(lines[line]))) {
798812
item = {
799813
'url': parts[3],
800-
'func': parts[4]
814+
'func': parts[4],
815+
'args': [],
816+
'line': +parts[1],
817+
'column': null // TODO: Check to see if inline#1 (+parts[2]) points to the script number or column number.
801818
};
802819
var relativeLine = (+parts[1]); // relative to the start of the <SCRIPT> block
803820
var script = inlineScriptBlocks[parts[2] - 1];
804821
if (script) {
805-
source = getSource(item.url);
822+
var source = getSource(item.url);
806823
if (source) {
807824
source = source.join('\n');
808825
var pos = source.indexOf(script.innerText);
@@ -811,15 +828,16 @@ TraceKit.computeStackTrace = (function computeStackTraceWrapper() {
811828
}
812829
}
813830
}
814-
} else if ((parts = lineRE3.exec(lines[i]))) {
815-
var url = window.location.href.replace(/#.*$/, ''),
816-
line = parts[1];
817-
var re = new RegExp(escapeCodeAsRegExpForMatchingInsideHTML(lines[i + 1]));
818-
source = findSourceInUrls(re, [url]);
831+
} else if ((parts = lineRE3.exec(lines[line]))) {
832+
var url = window.location.href.replace(/#.*$/, '');
833+
var re = new RegExp(escapeCodeAsRegExpForMatchingInsideHTML(lines[line + 1]));
834+
var src = findSourceInUrls(re, [url]);
819835
item = {
820836
'url': url,
821-
'line': source ? source.line : line,
822-
'func': ''
837+
'func': '',
838+
'args': [],
839+
'line': src ? src.line : parts[1],
840+
'column': null
823841
};
824842
}
825843

@@ -829,15 +847,16 @@ TraceKit.computeStackTrace = (function computeStackTraceWrapper() {
829847
}
830848
var context = gatherContext(item.url, item.line);
831849
var midline = (context ? context[Math.floor(context.length / 2)] : null);
832-
if (context && midline.replace(/^\s*/, '') === lines[i + 1].replace(/^\s*/, '')) {
850+
if (context && midline.replace(/^\s*/, '') === lines[line + 1].replace(/^\s*/, '')) {
833851
item.context = context;
834852
} else {
835853
// if (context) alert("Context mismatch. Correct midline:\n" + lines[i+1] + "\n\nMidline:\n" + midline + "\n\nContext:\n" + context.join("\n") + "\n\nURL:\n" + item.url);
836-
item.context = [lines[i + 1]];
854+
item.context = [lines[line + 1]];
837855
}
838856
stack.push(item);
839857
}
840858
}
859+
841860
if (!stack.length) {
842861
return null; // could not parse multiline exception message as Opera stack trace
843862
}

0 commit comments

Comments
 (0)