Skip to content

Commit 3e28135

Browse files
committed
Parse nested eval locations and set evalOrigin
Issue: #32
1 parent a3bf972 commit 3e28135

7 files changed

+470
-691
lines changed

dist/error-stack-parser.js

+40-3
Original file line numberDiff line numberDiff line change
@@ -48,19 +48,55 @@
4848
return [parts[1], parts[2] || undefined, parts[3] || undefined];
4949
},
5050

51+
/**
52+
* Given part of a raw stackframe matching 'eval ...', return a possibly nested StackFrame representing
53+
* an evalOrigin.
54+
*
55+
* @param {String} partialFrame matching an eval expression of a stackframe
56+
* @returns {StackFrame} eval origin frame
57+
*/
58+
parseEvalOrigin: function ErrorStackParser$$parseEvalOrigin(partialFrame) {
59+
if (partialFrame == null || partialFrame.length < 7) {
60+
return undefined;
61+
}
62+
63+
var sanitizedLine = partialFrame
64+
.replace(/(\(eval at [^()]+ \([^()]+\)\), )/g, '') // Remove nested eval
65+
.replace(/ \([^()]+\),?/g, '') // Remove top level location and trailing comma
66+
.replace(/eval (code )?/g, '') // Remove remaining "eval ..." prefix
67+
68+
var location = sanitizedLine.match(/ ((\S+):(\d+):(\d+)$)/);
69+
// remove the location from the line, if it was matched
70+
sanitizedLine = location ? sanitizedLine.replace(location[0], '') : sanitizedLine;
71+
72+
var tokens = sanitizedLine.split(/\s+/).slice(1);
73+
// if a location was matched, pass it to extractLocation() otherwise pop the last token
74+
var locationParts = this.extractLocation(location ? location[1] : '');
75+
var functionName = tokens.join(' ') || undefined;
76+
var fileName = ['eval', '<anonymous>', ''].indexOf(locationParts[0]) > -1 ? undefined : locationParts[0];
77+
return new StackFrame({
78+
functionName: functionName,
79+
fileName: fileName,
80+
lineNumber: locationParts[1],
81+
columnNumber: locationParts[2],
82+
source: partialFrame,
83+
evalOrigin: this.parseEvalOrigin(partialFrame.substring(partialFrame.indexOf('(eval ') + 1, partialFrame.lastIndexOf(')')))
84+
});
85+
},
86+
5187
parseV8OrIE: function ErrorStackParser$$parseV8OrIE(error) {
5288
var filtered = error.stack.split('\n').filter(function(line) {
5389
return !!line.match(CHROME_IE_STACK_REGEXP);
5490
}, this);
5591

5692
return filtered.map(function(line) {
5793
if (line.indexOf('(eval ') > -1) {
58-
// Throw away eval information until we implement stacktrace.js/stackframe#8
94+
var evalOrigin = this.parseEvalOrigin(line.substring(line.indexOf('(eval ') + 1, line.lastIndexOf(')')))
5995
line = line.replace(/eval code/g, 'eval').replace(/(\(eval at [^()]*)|(\),.*$)/g, '');
6096
}
6197
var sanitizedLine = line.replace(/^\s+/, '').replace(/\(eval code/g, '(');
6298

63-
// capture and preseve the parenthesized location "(/foo/my bar.js:12:87)" in
99+
// capture and preserve the parenthesized location "(/foo/my bar.js:12:87)" in
64100
// case it has spaces in it, as the string is split on \s+ later on
65101
var location = sanitizedLine.match(/ (\((.+):(\d+):(\d+)\)$)/);
66102

@@ -78,7 +114,8 @@
78114
fileName: fileName,
79115
lineNumber: locationParts[1],
80116
columnNumber: locationParts[2],
81-
source: line
117+
source: line,
118+
evalOrigin: evalOrigin
82119
});
83120
}, this);
84121
},

dist/error-stack-parser.min.js

+1-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)