|
17 | 17 | var CHROME_IE_STACK_REGEXP = /^\s*at .*(\S+\:\d+|\(native\))/m; |
18 | 18 | var SAFARI_NATIVE_CODE_REGEXP = /^(eval@)?(\[native code\])?$/; |
19 | 19 |
|
| 20 | + function _map(array, fn, thisArg) { |
| 21 | + if (typeof Array.prototype.map === 'function') { |
| 22 | + return array.map(fn, thisArg); |
| 23 | + } else { |
| 24 | + var output = new Array(array.length); |
| 25 | + for (var i = 0; i < array.length; i++) { |
| 26 | + output[i] = fn.call(thisArg, array[i]); |
| 27 | + } |
| 28 | + return output; |
| 29 | + } |
| 30 | + } |
| 31 | + |
| 32 | + function _filter(array, fn, thisArg) { |
| 33 | + if (typeof Array.prototype.filter === 'function') { |
| 34 | + return array.filter(fn, thisArg); |
| 35 | + } else { |
| 36 | + var output = []; |
| 37 | + for (var i = 0; i < array.length; i++) { |
| 38 | + if (fn.call(thisArg, array[i])) { |
| 39 | + output.push(array[i]); |
| 40 | + } |
| 41 | + } |
| 42 | + return output; |
| 43 | + } |
| 44 | + } |
| 45 | + |
20 | 46 | return { |
21 | 47 | /** |
22 | 48 | * Given an Error object, extract the most information from it. |
|
28 | 54 | return this.parseOpera(error); |
29 | 55 | } else if (error.stack && error.stack.match(CHROME_IE_STACK_REGEXP)) { |
30 | 56 | return this.parseV8OrIE(error); |
31 | | - } else if (error.stack && error.stack.match(FIREFOX_SAFARI_STACK_REGEXP)) { |
| 57 | + } else if (error.stack) { |
32 | 58 | return this.parseFFOrSafari(error); |
33 | 59 | } else { |
34 | 60 | throw new Error('Cannot parse given Error object'); |
|
58 | 84 | }, |
59 | 85 |
|
60 | 86 | parseV8OrIE: function ErrorStackParser$$parseV8OrIE(error) { |
61 | | - return error.stack.split('\n').filter(function (line) { |
| 87 | + var filtered = _filter(error.stack.split('\n'), function (line) { |
62 | 88 | return !!line.match(CHROME_IE_STACK_REGEXP); |
63 | | - }, this).map(function (line) { |
| 89 | + }, this); |
| 90 | + |
| 91 | + return _map(filtered, function (line) { |
64 | 92 | if (line.indexOf('(eval ') > -1) { |
65 | 93 | // Throw away eval information until we implement stacktrace.js/stackframe#8 |
66 | 94 | line = line.replace(/eval code/g, 'eval').replace(/(\(eval at [^\()]*)|(\)\,.*$)/g, ''); |
|
75 | 103 | }, |
76 | 104 |
|
77 | 105 | parseFFOrSafari: function ErrorStackParser$$parseFFOrSafari(error) { |
78 | | - return error.stack.split('\n').filter(function (line) { |
| 106 | + var filtered = _filter(error.stack.split('\n'), function (line) { |
79 | 107 | return !line.match(SAFARI_NATIVE_CODE_REGEXP); |
80 | | - }, this).map(function (line) { |
| 108 | + }, this); |
| 109 | + |
| 110 | + return _map(filtered, function (line) { |
81 | 111 | // Throw away eval information until we implement stacktrace.js/stackframe#8 |
82 | 112 | if (line.indexOf(' > eval') > -1) { |
83 | 113 | line = line.replace(/ line (\d+)(?: > eval line \d+)* > eval\:\d+\:\d+/g, ':$1'); |
|
138 | 168 |
|
139 | 169 | // Opera 10.65+ Error.stack very similar to FF/Safari |
140 | 170 | parseOpera11: function ErrorStackParser$$parseOpera11(error) { |
141 | | - return error.stack.split('\n').filter(function (line) { |
| 171 | + var filtered = _filter(error.stack.split('\n'), function (line) { |
142 | 172 | return !!line.match(FIREFOX_SAFARI_STACK_REGEXP) && |
143 | 173 | !line.match(/^Error created at/); |
144 | | - }, this).map(function (line) { |
| 174 | + }, this); |
| 175 | + |
| 176 | + return _map(filtered, function (line) { |
145 | 177 | var tokens = line.split('@'); |
146 | 178 | var locationParts = this.extractLocation(tokens.pop()); |
147 | 179 | var functionCall = (tokens.shift() || ''); |
|
0 commit comments