1 |
|
2 | var ParsedError, prop, sysPath, _fn, _i, _len, _ref;
|
3 |
|
4 | sysPath = require('path');
|
5 |
|
6 | module.exports = ParsedError = (function() {
|
7 | function ParsedError(error) {
|
8 | this.error = error;
|
9 | this._parse();
|
10 | }
|
11 |
|
12 | ParsedError.prototype._parse = function() {
|
13 | var m;
|
14 | this._trace = [];
|
15 | this._kind = 'Error';
|
16 | this._wrapper = '';
|
17 | if (this.error.wrapper != null) {
|
18 | this._wrapper = String(this.error.wrapper);
|
19 | }
|
20 | if (typeof this.error !== 'object') {
|
21 | this._message = String(this.error);
|
22 | } else {
|
23 | this._stack = this.error.stack;
|
24 | if (this.error.kind != null) {
|
25 | this._kind = String(this.error.kind);
|
26 | } else if (typeof this._stack === 'string') {
|
27 | if (m = this._stack.match(/^([a-zA-Z0-9\_\$]+):\ /)) {
|
28 | this._kind = m[1];
|
29 | }
|
30 | }
|
31 | this._message = (this.error.message != null) && String(this.error.message) || '';
|
32 | if (typeof this._stack === 'string') {
|
33 | this._parseStack();
|
34 | }
|
35 | }
|
36 | };
|
37 |
|
38 | ParsedError.prototype._parseStack = function() {
|
39 | var line, message, messageLines, reachedTrace, _i, _len, _ref;
|
40 | messageLines = [];
|
41 | reachedTrace = false;
|
42 | _ref = this._stack.split('\n');
|
43 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
44 | line = _ref[_i];
|
45 | if (line.trim() === '') {
|
46 | continue;
|
47 | }
|
48 | if (reachedTrace) {
|
49 | this._trace.push(this._parseTraceItem(line));
|
50 | } else {
|
51 | if (line.match(/^\s*at\s.+/)) {
|
52 | reachedTrace = true;
|
53 | this._trace.push(this._parseTraceItem(line));
|
54 | } else if (!this._message.split('\n'.indexOf(line))) {
|
55 | messageLines.push(line);
|
56 | }
|
57 | }
|
58 | }
|
59 | message = messageLines.join('\n');
|
60 | if (message.substr(0, this._kind.length) === this._kind) {
|
61 | message = message.substr(this._kind.length, message.length).replace(/^\:\s+/, '');
|
62 | }
|
63 | if (message.length) {
|
64 | this._message = this._message.length ? [this._message, message].join('\n') : message;
|
65 | }
|
66 | };
|
67 |
|
68 | ParsedError.prototype._parseTraceItem = function(text) {
|
69 | var addr, col, d, dir, file, jsCol, jsLine, line, m, original, packageName, packages, path, r, remaining, shortenedAddr, shortenedPath, what;
|
70 | text = text.trim();
|
71 | if (text === '') {
|
72 | return;
|
73 | }
|
74 | if (!text.match(/^at\ /)) {
|
75 | return text;
|
76 | }
|
77 | text = text.replace(/^at /, '');
|
78 | if (text === 'Error (<anonymous>)' || text === 'Error (<anonymous>:null:null)') {
|
79 | return;
|
80 | }
|
81 | original = text;
|
82 | what = null;
|
83 | addr = null;
|
84 | path = null;
|
85 | dir = null;
|
86 | file = null;
|
87 | line = null;
|
88 | col = null;
|
89 | jsLine = null;
|
90 | jsCol = null;
|
91 | shortenedPath = null;
|
92 | shortenedAddr = null;
|
93 | packageName = '[current]';
|
94 | if (m = text.match(/\(([^\)]+)\)$/)) {
|
95 | addr = m[1].trim();
|
96 | }
|
97 | if (addr != null) {
|
98 | what = text.substr(0, text.length - addr.length - 2);
|
99 | what = what.trim();
|
100 | }
|
101 | if (addr == null) {
|
102 | addr = text.trim();
|
103 | }
|
104 | addr = this._fixPath(addr);
|
105 | remaining = addr;
|
106 | if (m = remaining.match(/\,\ <js>:(\d+):(\d+)$/)) {
|
107 | jsLine = m[1];
|
108 | jsCol = m[2];
|
109 | remaining = remaining.substr(0, remaining.length - m[0].length);
|
110 | }
|
111 | if (m = remaining.match(/:(\d+):(\d+)$/)) {
|
112 | line = m[1];
|
113 | col = m[2];
|
114 | remaining = remaining.substr(0, remaining.length - m[0].length);
|
115 | path = remaining;
|
116 | }
|
117 | if (path != null) {
|
118 | file = sysPath.basename(path);
|
119 | dir = sysPath.dirname(path);
|
120 | if (dir === '.') {
|
121 | dir = '';
|
122 | }
|
123 | path = this._fixPath(path);
|
124 | file = this._fixPath(file);
|
125 | dir = this._fixPath(dir);
|
126 | }
|
127 | if (dir != null) {
|
128 | d = dir.replace(/[\\]{1,2}/g, '/');
|
129 | if (m = d.match(/node_modules\/([^\/]+)(?!.*node_modules.*)/)) {
|
130 | packageName = m[1];
|
131 | }
|
132 | }
|
133 | if (jsLine == null) {
|
134 | jsLine = line;
|
135 | jsCol = col;
|
136 | }
|
137 | if (path != null) {
|
138 | r = this._rectifyPath(path);
|
139 | shortenedPath = r.path;
|
140 | shortenedAddr = shortenedPath + addr.substr(path.length, addr.length);
|
141 | packages = r.packages;
|
142 | }
|
143 | return {
|
144 | original: original,
|
145 | what: what,
|
146 | addr: addr,
|
147 | path: path,
|
148 | dir: dir,
|
149 | file: file,
|
150 | line: parseInt(line),
|
151 | col: parseInt(col),
|
152 | jsLine: parseInt(jsLine),
|
153 | jsCol: parseInt(jsCol),
|
154 | packageName: packageName,
|
155 | shortenedPath: shortenedPath,
|
156 | shortenedAddr: shortenedAddr,
|
157 | packages: packages || []
|
158 | };
|
159 | };
|
160 |
|
161 | ParsedError.prototype._getMessage = function() {
|
162 | return this._message;
|
163 | };
|
164 |
|
165 | ParsedError.prototype._getKind = function() {
|
166 | return this._kind;
|
167 | };
|
168 |
|
169 | ParsedError.prototype._getWrapper = function() {
|
170 | return this._wrapper;
|
171 | };
|
172 |
|
173 | ParsedError.prototype._getStack = function() {
|
174 | return this._stack;
|
175 | };
|
176 |
|
177 | ParsedError.prototype._getArguments = function() {
|
178 | return this.error["arguments"];
|
179 | };
|
180 |
|
181 | ParsedError.prototype._getType = function() {
|
182 | return this.error.type;
|
183 | };
|
184 |
|
185 | ParsedError.prototype._getTrace = function() {
|
186 | return this._trace;
|
187 | };
|
188 |
|
189 | ParsedError.prototype._fixPath = function(path) {
|
190 | return path.replace(/[\\]{1,2}/g, '/');
|
191 | };
|
192 |
|
193 | ParsedError.prototype._rectifyPath = function(path, nameForCurrentPackage) {
|
194 | var m, packages, parts, remaining, rest;
|
195 | path = String(path);
|
196 | remaining = path;
|
197 | if (!(m = path.match(/^(.+?)\/node_modules\/(.+)$/))) {
|
198 | return {
|
199 | path: path,
|
200 | packages: []
|
201 | };
|
202 | }
|
203 | parts = [];
|
204 | packages = [];
|
205 | if (typeof nameForCurrentPackage === 'string') {
|
206 | parts.push("[" + nameForCurrentPackage + "]");
|
207 | packages.push("[" + nameForCurrentPackage + "]");
|
208 | } else {
|
209 | parts.push("[" + (m[1].match(/([^\/]+)$/)[1]) + "]");
|
210 | packages.push(m[1].match(/([^\/]+)$/)[1]);
|
211 | }
|
212 | rest = m[2];
|
213 | while (m = rest.match(/([^\/]+)\/node_modules\/(.+)$/)) {
|
214 | parts.push("[" + m[1] + "]");
|
215 | packages.push(m[1]);
|
216 | rest = m[2];
|
217 | }
|
218 | if (m = rest.match(/([^\/]+)\/(.+)$/)) {
|
219 | parts.push("[" + m[1] + "]");
|
220 | packages.push(m[1]);
|
221 | rest = m[2];
|
222 | }
|
223 | parts.push(rest);
|
224 | return {
|
225 | path: parts.join("/"),
|
226 | packages: packages
|
227 | };
|
228 | };
|
229 |
|
230 | return ParsedError;
|
231 |
|
232 | })();
|
233 |
|
234 | _ref = ['message', 'kind', 'arguments', 'type', 'stack', 'trace', 'wrapper'];
|
235 | _fn = function() {
|
236 | var methodName;
|
237 | methodName = '_get' + prop[0].toUpperCase() + prop.substr(1, prop.length);
|
238 | return Object.defineProperty(ParsedError.prototype, prop, {
|
239 | get: function() {
|
240 | return this[methodName]();
|
241 | }
|
242 | });
|
243 | };
|
244 | for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
245 | prop = _ref[_i];
|
246 | _fn();
|
247 | }
|