|
48 | 48 | return [parts[1], parts[2] || undefined, parts[3] || undefined];
|
49 | 49 | },
|
50 | 50 |
|
| 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 | + |
51 | 87 | parseV8OrIE: function ErrorStackParser$$parseV8OrIE(error) {
|
52 | 88 | var filtered = error.stack.split('\n').filter(function(line) {
|
53 | 89 | return !!line.match(CHROME_IE_STACK_REGEXP);
|
54 | 90 | }, this);
|
55 | 91 |
|
56 | 92 | return filtered.map(function(line) {
|
57 | 93 | 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(')'))) |
59 | 95 | line = line.replace(/eval code/g, 'eval').replace(/(\(eval at [^()]*)|(\),.*$)/g, '');
|
60 | 96 | }
|
61 | 97 | var sanitizedLine = line.replace(/^\s+/, '').replace(/\(eval code/g, '(');
|
62 | 98 |
|
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 |
64 | 100 | // case it has spaces in it, as the string is split on \s+ later on
|
65 | 101 | var location = sanitizedLine.match(/ (\((.+):(\d+):(\d+)\)$)/);
|
66 | 102 |
|
|
78 | 114 | fileName: fileName,
|
79 | 115 | lineNumber: locationParts[1],
|
80 | 116 | columnNumber: locationParts[2],
|
81 |
| - source: line |
| 117 | + source: line, |
| 118 | + evalOrigin: evalOrigin |
82 | 119 | });
|
83 | 120 | }, this);
|
84 | 121 | },
|
|
0 commit comments