rollbar 2.26.2 → 2.26.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/ci.yml +32 -10
- package/.lgtm.yml +7 -7
- package/.prettierignore +18 -0
- package/.vscode/settings.json +39 -0
- package/CHANGELOG.md +121 -35
- package/Gruntfile.js +51 -71
- package/README.md +2 -4
- package/bower.json +1 -3
- package/defaults.js +17 -5
- package/dist/plugins/jquery.min.js +1 -1
- package/dist/rollbar.js +5699 -5052
- package/dist/rollbar.js.map +1 -1
- package/dist/rollbar.min.js +1 -1
- package/dist/rollbar.min.js.map +1 -1
- package/dist/rollbar.named-amd.js +5704 -5062
- package/dist/rollbar.named-amd.js.map +1 -1
- package/dist/rollbar.named-amd.min.js +1 -1
- package/dist/rollbar.named-amd.min.js.map +1 -1
- package/dist/rollbar.noconflict.umd.js +5693 -5052
- package/dist/rollbar.noconflict.umd.js.map +1 -1
- package/dist/rollbar.noconflict.umd.min.js +1 -1
- package/dist/rollbar.noconflict.umd.min.js.map +1 -1
- package/dist/rollbar.snippet.js +1 -1
- package/dist/rollbar.umd.js +5704 -5063
- package/dist/rollbar.umd.js.map +1 -1
- package/dist/rollbar.umd.min.js +1 -1
- package/dist/rollbar.umd.min.js.map +1 -1
- package/docs/extension-exceptions.md +35 -30
- package/docs/migration_v0_to_v1.md +41 -38
- package/index.d.ts +270 -231
- package/karma.conf.js +16 -34
- package/package.json +21 -17
- package/prettier.config.js +7 -0
- package/src/api.js +21 -10
- package/src/apiUtility.js +12 -8
- package/src/browser/core.js +103 -65
- package/src/browser/defaults/scrubFields.js +3 -3
- package/src/browser/detection.js +7 -8
- package/src/browser/domUtility.js +18 -8
- package/src/browser/globalSetup.js +12 -6
- package/src/browser/logger.js +1 -1
- package/src/browser/plugins/jquery.js +35 -35
- package/src/browser/predicates.js +1 -1
- package/src/browser/rollbar.js +1 -1
- package/src/browser/rollbarWrapper.js +8 -5
- package/src/browser/shim.js +43 -19
- package/src/browser/snippet_callback.js +6 -4
- package/src/browser/telemetry.js +573 -354
- package/src/browser/transforms.js +46 -27
- package/src/browser/transport/fetch.js +16 -14
- package/src/browser/transport/xhr.js +29 -13
- package/src/browser/transport.js +82 -25
- package/src/browser/url.js +16 -8
- package/src/browser/wrapGlobals.js +27 -8
- package/src/defaults.js +3 -3
- package/src/errorParser.js +14 -11
- package/src/merge.js +32 -23
- package/src/notifier.js +16 -13
- package/src/predicates.js +43 -23
- package/src/queue.js +71 -39
- package/src/rateLimiter.js +59 -18
- package/src/react-native/logger.js +1 -1
- package/src/react-native/rollbar.js +59 -55
- package/src/react-native/transforms.js +13 -9
- package/src/react-native/transport.js +44 -34
- package/src/rollbar.js +22 -13
- package/src/scrub.js +0 -1
- package/src/server/locals.js +69 -39
- package/src/server/logger.js +4 -4
- package/src/server/parser.js +72 -47
- package/src/server/rollbar.js +133 -55
- package/src/server/sourceMap/stackTrace.js +33 -18
- package/src/server/telemetry/urlHelpers.js +9 -11
- package/src/server/telemetry.js +68 -45
- package/src/server/transforms.js +37 -21
- package/src/server/transport.js +62 -32
- package/src/telemetry.js +92 -28
- package/src/transforms.js +33 -21
- package/src/truncation.js +8 -5
- package/src/utility/headers.js +43 -43
- package/src/utility/replace.js +9 -0
- package/src/utility/traverse.js +1 -1
- package/src/utility.js +89 -52
- package/test/api.test.js +31 -29
- package/test/apiUtility.test.js +43 -44
- package/test/browser.core.test.js +141 -131
- package/test/browser.domUtility.test.js +52 -35
- package/test/browser.predicates.test.js +13 -13
- package/test/browser.rollbar.test.js +597 -503
- package/test/browser.telemetry.test.js +76 -0
- package/test/browser.transforms.test.js +146 -128
- package/test/browser.transport.test.js +54 -46
- package/test/browser.url.test.js +12 -11
- package/test/fixtures/locals.fixtures.js +245 -126
- package/test/notifier.test.js +90 -78
- package/test/predicates.test.js +260 -214
- package/test/queue.test.js +230 -214
- package/test/rateLimiter.test.js +50 -42
- package/test/react-native.rollbar.test.js +149 -115
- package/test/react-native.transforms.test.js +21 -23
- package/test/react-native.transport.test.js +23 -11
- package/test/server.lambda.test.js +70 -53
- package/test/server.locals.test.js +437 -210
- package/test/server.parser.test.js +32 -26
- package/test/server.predicates.test.js +45 -43
- package/test/server.rollbar.test.js +311 -259
- package/test/server.telemetry.test.js +208 -83
- package/test/server.transforms.test.js +455 -361
- package/test/server.transport.test.js +144 -76
- package/test/telemetry.test.js +46 -37
- package/test/transforms.test.js +68 -66
- package/test/truncation.test.js +55 -53
- package/test/utility.test.js +266 -222
- package/webpack.config.js +46 -43
- package/.gitmodules +0 -3
- package/browserstack.browsers.js +0 -153
- package/browserstack.browsers.json +0 -4384
package/src/rollbar.js
CHANGED
|
@@ -38,7 +38,7 @@ function Rollbar(options, api, logger, telemeter, platform) {
|
|
|
38
38
|
|
|
39
39
|
var defaultOptions = {
|
|
40
40
|
maxItems: 0,
|
|
41
|
-
itemsPerMinute: 60
|
|
41
|
+
itemsPerMinute: 60,
|
|
42
42
|
};
|
|
43
43
|
|
|
44
44
|
Rollbar.rateLimiter = new RateLimiter(defaultOptions);
|
|
@@ -74,7 +74,7 @@ Rollbar.prototype.configure = function (options, payloadData) {
|
|
|
74
74
|
this.global(this.options);
|
|
75
75
|
|
|
76
76
|
if (validateTracer(options.tracer)) {
|
|
77
|
-
this.tracer = options.tracer
|
|
77
|
+
this.tracer = options.tracer;
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
return this;
|
|
@@ -153,7 +153,8 @@ Rollbar.prototype._log = function (defaultLevel, item) {
|
|
|
153
153
|
this._addTracingInfo(item);
|
|
154
154
|
item.level = item.level || defaultLevel;
|
|
155
155
|
this.telemeter && this.telemeter._captureRollbarItem(item);
|
|
156
|
-
item.telemetryEvents =
|
|
156
|
+
item.telemetryEvents =
|
|
157
|
+
(this.telemeter && this.telemeter.copyEvents()) || [];
|
|
157
158
|
this.notifier.log(item, callback);
|
|
158
159
|
} catch (e) {
|
|
159
160
|
if (callback) {
|
|
@@ -191,8 +192,14 @@ Rollbar.prototype._addTracingInfo = function (item) {
|
|
|
191
192
|
span.setTag('rollbar.error_uuid', item.uuid);
|
|
192
193
|
span.setTag('rollbar.has_error', true);
|
|
193
194
|
span.setTag('error', true);
|
|
194
|
-
span.setTag(
|
|
195
|
-
|
|
195
|
+
span.setTag(
|
|
196
|
+
'rollbar.item_url',
|
|
197
|
+
`https://rollbar.com/item/uuid/?uuid=${item.uuid}`,
|
|
198
|
+
);
|
|
199
|
+
span.setTag(
|
|
200
|
+
'rollbar.occurrence_url',
|
|
201
|
+
`https://rollbar.com/occurrence/uuid/?uuid=${item.uuid}`,
|
|
202
|
+
);
|
|
196
203
|
|
|
197
204
|
// add span ID & trace ID to occurrence
|
|
198
205
|
var opentracingSpanId = span.context().toSpanId();
|
|
@@ -204,12 +211,12 @@ Rollbar.prototype._addTracingInfo = function (item) {
|
|
|
204
211
|
} else {
|
|
205
212
|
item.custom = {
|
|
206
213
|
opentracing_span_id: opentracingSpanId,
|
|
207
|
-
opentracing_trace_id: opentracingTraceId
|
|
214
|
+
opentracing_trace_id: opentracingTraceId,
|
|
208
215
|
};
|
|
209
216
|
}
|
|
210
217
|
}
|
|
211
218
|
}
|
|
212
|
-
}
|
|
219
|
+
};
|
|
213
220
|
|
|
214
221
|
function generateItemHash(item) {
|
|
215
222
|
var message = item.message || '';
|
|
@@ -260,12 +267,14 @@ function validateSpan(span) {
|
|
|
260
267
|
|
|
261
268
|
var spanContext = span.context();
|
|
262
269
|
|
|
263
|
-
if (
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
270
|
+
if (
|
|
271
|
+
!spanContext ||
|
|
272
|
+
!spanContext.toSpanId ||
|
|
273
|
+
!spanContext.toTraceId ||
|
|
274
|
+
typeof spanContext.toSpanId !== 'function' ||
|
|
275
|
+
typeof spanContext.toTraceId !== 'function'
|
|
276
|
+
) {
|
|
277
|
+
return false;
|
|
269
278
|
}
|
|
270
279
|
|
|
271
280
|
return true;
|
package/src/scrub.js
CHANGED
package/src/server/locals.js
CHANGED
|
@@ -15,8 +15,8 @@ var DEFAULT_OPTIONS = {
|
|
|
15
15
|
uncaughtOnly: true,
|
|
16
16
|
depth: 1,
|
|
17
17
|
maxProperties: 30,
|
|
18
|
-
maxArray: 5
|
|
19
|
-
}
|
|
18
|
+
maxArray: 5,
|
|
19
|
+
};
|
|
20
20
|
|
|
21
21
|
function Locals(options, logger) {
|
|
22
22
|
if (!(this instanceof Locals)) {
|
|
@@ -31,7 +31,7 @@ function Locals(options, logger) {
|
|
|
31
31
|
this.initSession();
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
Locals.prototype.initSession = function() {
|
|
34
|
+
Locals.prototype.initSession = function () {
|
|
35
35
|
if (Locals.session) {
|
|
36
36
|
this.disconnectSession();
|
|
37
37
|
}
|
|
@@ -62,33 +62,39 @@ Locals.prototype.initSession = function() {
|
|
|
62
62
|
self.initialized = true;
|
|
63
63
|
updatePauseState(self.options, self.logger);
|
|
64
64
|
});
|
|
65
|
-
}
|
|
65
|
+
};
|
|
66
66
|
|
|
67
|
-
Locals.prototype.disconnectSession = function() {
|
|
67
|
+
Locals.prototype.disconnectSession = function () {
|
|
68
68
|
if (Locals.session) {
|
|
69
69
|
updatePauseState({ enabled: false }, this.logger);
|
|
70
70
|
Locals.session.disconnect();
|
|
71
71
|
Locals.session = null;
|
|
72
72
|
}
|
|
73
|
-
}
|
|
73
|
+
};
|
|
74
74
|
|
|
75
|
-
Locals.prototype.updateOptions = function(options) {
|
|
76
|
-
var pauseStateChanged =
|
|
75
|
+
Locals.prototype.updateOptions = function (options) {
|
|
76
|
+
var pauseStateChanged =
|
|
77
|
+
this.options.enabled != options.enabled ||
|
|
78
|
+
this.options.uncaughtOnly != options.uncaughtOnly;
|
|
77
79
|
|
|
78
80
|
this.options = _.merge(this.options, options);
|
|
79
81
|
|
|
80
82
|
if (this.initialized && pauseStateChanged) {
|
|
81
83
|
updatePauseState(this.options, this.logger);
|
|
82
84
|
}
|
|
83
|
-
}
|
|
85
|
+
};
|
|
84
86
|
|
|
85
87
|
function updatePauseState(options, logger) {
|
|
86
88
|
var state = pauseStateFromOptions(options);
|
|
87
|
-
Locals.session.post(
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
89
|
+
Locals.session.post(
|
|
90
|
+
'Debugger.setPauseOnExceptions',
|
|
91
|
+
{ state: state },
|
|
92
|
+
(err, _result) => {
|
|
93
|
+
if (err) {
|
|
94
|
+
logger.error('error in setPauseOnExceptions', err);
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
);
|
|
92
98
|
}
|
|
93
99
|
|
|
94
100
|
function pauseStateFromOptions(options) {
|
|
@@ -103,11 +109,11 @@ function pauseStateFromOptions(options) {
|
|
|
103
109
|
}
|
|
104
110
|
}
|
|
105
111
|
|
|
106
|
-
Locals.prototype.currentLocalsMap = function() {
|
|
112
|
+
Locals.prototype.currentLocalsMap = function () {
|
|
107
113
|
return new Map(Locals.currentErrors);
|
|
108
|
-
}
|
|
114
|
+
};
|
|
109
115
|
|
|
110
|
-
Locals.prototype.mergeLocals = function(localsMap, stack, key, callback) {
|
|
116
|
+
Locals.prototype.mergeLocals = function (localsMap, stack, key, callback) {
|
|
111
117
|
var matchedFrames;
|
|
112
118
|
|
|
113
119
|
try {
|
|
@@ -124,22 +130,26 @@ Locals.prototype.mergeLocals = function(localsMap, stack, key, callback) {
|
|
|
124
130
|
}
|
|
125
131
|
|
|
126
132
|
getLocalScopesForFrames(matchedFrames, this.options, callback);
|
|
127
|
-
}
|
|
133
|
+
};
|
|
128
134
|
|
|
129
135
|
// Finds frames in localParams that match file and line locations in stack.
|
|
130
136
|
function matchFrames(localParams, stack) {
|
|
131
137
|
var matchedFrames = [];
|
|
132
|
-
var localIndex = 0,
|
|
138
|
+
var localIndex = 0,
|
|
139
|
+
stackIndex = 0;
|
|
133
140
|
var stackLength = stack.length;
|
|
134
141
|
var callFrames = localParams.callFrames;
|
|
135
142
|
var callFramesLength = callFrames.length;
|
|
136
143
|
|
|
137
144
|
for (; stackIndex < stackLength; stackIndex++) {
|
|
138
145
|
while (localIndex < callFramesLength) {
|
|
139
|
-
if (
|
|
146
|
+
if (
|
|
147
|
+
firstFrame(localIndex, stackIndex) ||
|
|
148
|
+
matchedFrame(callFrames[localIndex], stack[stackIndex])
|
|
149
|
+
) {
|
|
140
150
|
matchedFrames.push({
|
|
141
151
|
stackLocation: stack[stackIndex],
|
|
142
|
-
callFrame: callFrames[localIndex]
|
|
152
|
+
callFrame: callFrames[localIndex],
|
|
143
153
|
});
|
|
144
154
|
localIndex++;
|
|
145
155
|
break;
|
|
@@ -165,32 +175,38 @@ function matchedFrame(callFrame, stackLocation) {
|
|
|
165
175
|
|
|
166
176
|
// Node.js prefixes filename some URLs with 'file:///' in Debugger.callFrame,
|
|
167
177
|
// but with only '/' in the error.stack string. Remove the prefix to facilitate a match.
|
|
168
|
-
var callFrameUrl = callFrame.url.replace(/file:\/\//,'');
|
|
178
|
+
var callFrameUrl = callFrame.url.replace(/file:\/\//, '');
|
|
169
179
|
|
|
170
180
|
// lineNumber is zero indexed, so offset it.
|
|
171
181
|
var callFrameLine = callFrame.location.lineNumber + 1;
|
|
172
182
|
var callFrameColumn = callFrame.location.columnNumber;
|
|
173
183
|
|
|
174
|
-
return
|
|
184
|
+
return (
|
|
185
|
+
callFrameUrl === position.source &&
|
|
175
186
|
callFrameLine === position.line &&
|
|
176
|
-
callFrameColumn === position.column
|
|
187
|
+
callFrameColumn === position.column
|
|
188
|
+
);
|
|
177
189
|
}
|
|
178
190
|
|
|
179
191
|
function getLocalScopesForFrames(matchedFrames, options, callback) {
|
|
180
|
-
async.each(
|
|
192
|
+
async.each(
|
|
193
|
+
matchedFrames,
|
|
194
|
+
getLocalScopeForFrame.bind({ options: options }),
|
|
195
|
+
callback,
|
|
196
|
+
);
|
|
181
197
|
}
|
|
182
198
|
|
|
183
199
|
function getLocalScopeForFrame(matchedFrame, callback) {
|
|
184
200
|
var options = this.options;
|
|
185
201
|
var scopes = matchedFrame.callFrame.scopeChain;
|
|
186
202
|
|
|
187
|
-
var scope = scopes.find(scope => scope.type === 'local');
|
|
203
|
+
var scope = scopes.find((scope) => scope.type === 'local');
|
|
188
204
|
|
|
189
205
|
if (!scope) {
|
|
190
206
|
return callback(null); // Do nothing return success.
|
|
191
207
|
}
|
|
192
208
|
|
|
193
|
-
getProperties(scope.object.objectId, function(err, response){
|
|
209
|
+
getProperties(scope.object.objectId, function (err, response) {
|
|
194
210
|
if (err) {
|
|
195
211
|
return callback(err);
|
|
196
212
|
}
|
|
@@ -200,8 +216,8 @@ function getLocalScopeForFrame(matchedFrame, callback) {
|
|
|
200
216
|
var localsContext = {
|
|
201
217
|
localsObject: matchedFrame.stackLocation.locals,
|
|
202
218
|
options: options,
|
|
203
|
-
depth: options.depth
|
|
204
|
-
}
|
|
219
|
+
depth: options.depth,
|
|
220
|
+
};
|
|
205
221
|
async.each(locals, getLocalValue.bind(localsContext), callback);
|
|
206
222
|
});
|
|
207
223
|
}
|
|
@@ -234,11 +250,21 @@ function getLocalValue(local, callback) {
|
|
|
234
250
|
}
|
|
235
251
|
|
|
236
252
|
switch (local.value.type) {
|
|
237
|
-
case 'undefined':
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
case '
|
|
241
|
-
|
|
253
|
+
case 'undefined':
|
|
254
|
+
cb(null, 'undefined');
|
|
255
|
+
break;
|
|
256
|
+
case 'object':
|
|
257
|
+
getObjectValue(local, options, depth, cb);
|
|
258
|
+
break;
|
|
259
|
+
case 'function':
|
|
260
|
+
cb(null, getObjectType(local));
|
|
261
|
+
break;
|
|
262
|
+
case 'symbol':
|
|
263
|
+
cb(null, getSymbolValue(local));
|
|
264
|
+
break;
|
|
265
|
+
default:
|
|
266
|
+
cb(null, local.value.value);
|
|
267
|
+
break;
|
|
242
268
|
}
|
|
243
269
|
}
|
|
244
270
|
|
|
@@ -266,7 +292,7 @@ function getObjectValue(local, options, depth, callback) {
|
|
|
266
292
|
return callback(null, getObjectType(local));
|
|
267
293
|
}
|
|
268
294
|
|
|
269
|
-
getProperties(local.value.objectId, function(err, response){
|
|
295
|
+
getProperties(local.value.objectId, function (err, response) {
|
|
270
296
|
if (err) {
|
|
271
297
|
return callback(err);
|
|
272
298
|
}
|
|
@@ -277,13 +303,13 @@ function getObjectValue(local, options, depth, callback) {
|
|
|
277
303
|
var localsContext = {
|
|
278
304
|
localsObject: isArray ? [] : {},
|
|
279
305
|
options: options,
|
|
280
|
-
depth: depth - 1
|
|
281
|
-
}
|
|
306
|
+
depth: depth - 1,
|
|
307
|
+
};
|
|
282
308
|
|
|
283
309
|
// For arrays, use eachSeries to ensure order is preserved.
|
|
284
310
|
// Otherwise, use each for faster completion.
|
|
285
311
|
var iterator = isArray ? async.eachSeries : async.each;
|
|
286
|
-
iterator(properties, getLocalValue.bind(localsContext), function(error){
|
|
312
|
+
iterator(properties, getLocalValue.bind(localsContext), function (error) {
|
|
287
313
|
if (error) {
|
|
288
314
|
return callback(error);
|
|
289
315
|
}
|
|
@@ -294,7 +320,11 @@ function getObjectValue(local, options, depth, callback) {
|
|
|
294
320
|
}
|
|
295
321
|
|
|
296
322
|
function getProperties(objectId, callback) {
|
|
297
|
-
Locals.session.post(
|
|
323
|
+
Locals.session.post(
|
|
324
|
+
'Runtime.getProperties',
|
|
325
|
+
{ objectId: objectId, ownProperties: true },
|
|
326
|
+
callback,
|
|
327
|
+
);
|
|
298
328
|
}
|
|
299
329
|
|
|
300
330
|
module.exports = Locals;
|
package/src/server/logger.js
CHANGED
|
@@ -4,20 +4,20 @@ var verbose = true;
|
|
|
4
4
|
|
|
5
5
|
var logger = {
|
|
6
6
|
/* eslint-disable no-console */
|
|
7
|
-
log: function() {
|
|
7
|
+
log: function () {
|
|
8
8
|
if (verbose) {
|
|
9
9
|
console.log.apply(console, arguments);
|
|
10
10
|
}
|
|
11
11
|
},
|
|
12
|
-
error: function() {
|
|
12
|
+
error: function () {
|
|
13
13
|
if (verbose) {
|
|
14
14
|
console.error.apply(console, arguments);
|
|
15
15
|
}
|
|
16
16
|
},
|
|
17
17
|
/* eslint-enable no-console */
|
|
18
|
-
setVerbose: function(val) {
|
|
18
|
+
setVerbose: function (val) {
|
|
19
19
|
verbose = val;
|
|
20
|
-
}
|
|
20
|
+
},
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
module.exports = logger;
|
package/src/server/parser.js
CHANGED
|
@@ -14,19 +14,16 @@ var tracePattern =
|
|
|
14
14
|
var jadeTracePattern = /^\s*at .+ \(.+ (at[^)]+\))\)$/;
|
|
15
15
|
var jadeFramePattern = /^\s*(>?) [0-9]+\|(\s*.+)$/m;
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
var cache = new lru({max: 100});
|
|
17
|
+
var cache = new lru({ max: 100 });
|
|
19
18
|
var pendingReads = {};
|
|
20
19
|
|
|
21
20
|
exports.cache = cache;
|
|
22
21
|
exports.pendingReads = pendingReads;
|
|
23
22
|
|
|
24
|
-
|
|
25
23
|
/*
|
|
26
24
|
* Internal
|
|
27
25
|
*/
|
|
28
26
|
|
|
29
|
-
|
|
30
27
|
function getMultipleErrors(errors) {
|
|
31
28
|
var errArray, key;
|
|
32
29
|
|
|
@@ -52,10 +49,19 @@ function getMultipleErrors(errors) {
|
|
|
52
49
|
return errArray;
|
|
53
50
|
}
|
|
54
51
|
|
|
55
|
-
|
|
56
52
|
function parseJadeDebugFrame(body) {
|
|
57
|
-
var lines,
|
|
58
|
-
|
|
53
|
+
var lines,
|
|
54
|
+
lineNumSep,
|
|
55
|
+
filename,
|
|
56
|
+
lineno,
|
|
57
|
+
numLines,
|
|
58
|
+
msg,
|
|
59
|
+
i,
|
|
60
|
+
contextLine,
|
|
61
|
+
preContext,
|
|
62
|
+
postContext,
|
|
63
|
+
line,
|
|
64
|
+
jadeMatch;
|
|
59
65
|
|
|
60
66
|
// Given a Jade exception body, return a frame object
|
|
61
67
|
lines = body.split('\n');
|
|
@@ -90,7 +96,10 @@ function parseJadeDebugFrame(body) {
|
|
|
90
96
|
}
|
|
91
97
|
|
|
92
98
|
preContext = preContext.slice(0, Math.min(preContext.length, linesOfContext));
|
|
93
|
-
postContext = postContext.slice(
|
|
99
|
+
postContext = postContext.slice(
|
|
100
|
+
0,
|
|
101
|
+
Math.min(postContext.length, linesOfContext),
|
|
102
|
+
);
|
|
94
103
|
|
|
95
104
|
return {
|
|
96
105
|
frame: {
|
|
@@ -100,29 +109,32 @@ function parseJadeDebugFrame(body) {
|
|
|
100
109
|
code: contextLine,
|
|
101
110
|
context: {
|
|
102
111
|
pre: preContext,
|
|
103
|
-
post: postContext
|
|
104
|
-
}
|
|
112
|
+
post: postContext,
|
|
113
|
+
},
|
|
105
114
|
},
|
|
106
|
-
message: msg
|
|
115
|
+
message: msg,
|
|
107
116
|
};
|
|
108
117
|
}
|
|
109
118
|
|
|
110
|
-
|
|
111
119
|
function extractContextLines(frame, fileLines) {
|
|
112
120
|
frame.code = fileLines[frame.lineno - 1];
|
|
113
121
|
frame.context = {
|
|
114
|
-
pre: fileLines.slice(
|
|
115
|
-
|
|
122
|
+
pre: fileLines.slice(
|
|
123
|
+
Math.max(0, frame.lineno - (linesOfContext + 1)),
|
|
124
|
+
frame.lineno - 1,
|
|
125
|
+
),
|
|
126
|
+
post: fileLines.slice(frame.lineno, frame.lineno + linesOfContext),
|
|
116
127
|
};
|
|
117
128
|
}
|
|
118
129
|
|
|
119
130
|
function mapPosition(position, diagnostic) {
|
|
120
|
-
return stackTrace.mapSourcePosition(
|
|
131
|
+
return stackTrace.mapSourcePosition(
|
|
132
|
+
{
|
|
121
133
|
source: position.source,
|
|
122
134
|
line: position.line,
|
|
123
|
-
column: position.column
|
|
135
|
+
column: position.column,
|
|
124
136
|
},
|
|
125
|
-
diagnostic
|
|
137
|
+
diagnostic,
|
|
126
138
|
);
|
|
127
139
|
}
|
|
128
140
|
|
|
@@ -144,7 +156,7 @@ function parseFrameLine(line, callback) {
|
|
|
144
156
|
var runtimePosition = {
|
|
145
157
|
source: data[1],
|
|
146
158
|
line: Math.floor(data[2]),
|
|
147
|
-
column: Math.floor(data[3]) - 1
|
|
159
|
+
column: Math.floor(data[3]) - 1,
|
|
148
160
|
};
|
|
149
161
|
if (this.useSourceMaps) {
|
|
150
162
|
position = mapPosition(runtimePosition, this.diagnostic);
|
|
@@ -157,7 +169,7 @@ function parseFrameLine(line, callback) {
|
|
|
157
169
|
filename: position.source,
|
|
158
170
|
lineno: position.line,
|
|
159
171
|
colno: position.column,
|
|
160
|
-
runtimePosition: runtimePosition // Used to match frames for locals
|
|
172
|
+
runtimePosition: runtimePosition, // Used to match frames for locals
|
|
161
173
|
};
|
|
162
174
|
|
|
163
175
|
// For coffeescript, lineno and colno refer to the .coffee positions
|
|
@@ -173,7 +185,6 @@ function parseFrameLine(line, callback) {
|
|
|
173
185
|
callback(null, frame);
|
|
174
186
|
}
|
|
175
187
|
|
|
176
|
-
|
|
177
188
|
function shouldReadFrameFile(frameFilename, callback) {
|
|
178
189
|
var isValidFilename, isCached, isPending;
|
|
179
190
|
|
|
@@ -184,7 +195,6 @@ function shouldReadFrameFile(frameFilename, callback) {
|
|
|
184
195
|
callback(null, isValidFilename && !isCached && !isPending);
|
|
185
196
|
}
|
|
186
197
|
|
|
187
|
-
|
|
188
198
|
function readFileLines(filename, callback) {
|
|
189
199
|
try {
|
|
190
200
|
fs.readFile(filename, function (err, fileData) {
|
|
@@ -210,7 +220,6 @@ function checkFileExists(filename, callback) {
|
|
|
210
220
|
});
|
|
211
221
|
}
|
|
212
222
|
|
|
213
|
-
|
|
214
223
|
function gatherContexts(frames, callback) {
|
|
215
224
|
var frameFilenames = [];
|
|
216
225
|
|
|
@@ -280,7 +289,6 @@ function gatherContexts(frames, callback) {
|
|
|
280
289
|
});
|
|
281
290
|
});
|
|
282
291
|
});
|
|
283
|
-
|
|
284
292
|
});
|
|
285
293
|
}
|
|
286
294
|
|
|
@@ -288,7 +296,6 @@ function gatherContexts(frames, callback) {
|
|
|
288
296
|
* Public API
|
|
289
297
|
*/
|
|
290
298
|
|
|
291
|
-
|
|
292
299
|
exports.parseException = function (exc, options, item, callback) {
|
|
293
300
|
var multipleErrs = getMultipleErrors(exc.errors);
|
|
294
301
|
|
|
@@ -299,13 +306,13 @@ exports.parseException = function (exc, options, item, callback) {
|
|
|
299
306
|
logger.error('could not parse exception, err: ' + err);
|
|
300
307
|
return callback(err);
|
|
301
308
|
}
|
|
302
|
-
message = String(exc.message || '<no message>')
|
|
309
|
+
message = String(exc.message || '<no message>');
|
|
303
310
|
clss = String(exc.name || '<unknown>');
|
|
304
311
|
|
|
305
312
|
ret = {
|
|
306
313
|
class: clss,
|
|
307
314
|
message: message,
|
|
308
|
-
frames: stack
|
|
315
|
+
frames: stack,
|
|
309
316
|
};
|
|
310
317
|
|
|
311
318
|
if (multipleErrs && multipleErrs.length) {
|
|
@@ -313,7 +320,7 @@ exports.parseException = function (exc, options, item, callback) {
|
|
|
313
320
|
ret = {
|
|
314
321
|
class: clss,
|
|
315
322
|
message: String(firstErr.message || '<no message>'),
|
|
316
|
-
frames: stack
|
|
323
|
+
frames: stack,
|
|
317
324
|
};
|
|
318
325
|
}
|
|
319
326
|
|
|
@@ -325,25 +332,30 @@ exports.parseException = function (exc, options, item, callback) {
|
|
|
325
332
|
}
|
|
326
333
|
|
|
327
334
|
if (item.localsMap) {
|
|
328
|
-
item.notifier.locals.mergeLocals(
|
|
329
|
-
|
|
330
|
-
|
|
335
|
+
item.notifier.locals.mergeLocals(
|
|
336
|
+
item.localsMap,
|
|
337
|
+
stack,
|
|
338
|
+
exc.stack,
|
|
339
|
+
function (err) {
|
|
340
|
+
if (err) {
|
|
341
|
+
logger.error('could not parse locals, err: ' + err);
|
|
331
342
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
343
|
+
// Don't reject the occurrence, record the error instead.
|
|
344
|
+
item.diagnostic['error parsing locals'] = err;
|
|
345
|
+
}
|
|
335
346
|
|
|
336
|
-
|
|
337
|
-
|
|
347
|
+
return callback(null, ret);
|
|
348
|
+
},
|
|
349
|
+
);
|
|
338
350
|
} else {
|
|
339
351
|
return callback(null, ret);
|
|
340
352
|
}
|
|
341
353
|
});
|
|
342
354
|
};
|
|
343
355
|
|
|
344
|
-
|
|
345
356
|
exports.parseStack = function (stack, options, item, callback) {
|
|
346
|
-
var lines,
|
|
357
|
+
var lines,
|
|
358
|
+
_stack = stack;
|
|
347
359
|
|
|
348
360
|
// Some JS frameworks (e.g. Meteor) might bury the stack property
|
|
349
361
|
while (typeof _stack === 'object') {
|
|
@@ -359,14 +371,27 @@ exports.parseStack = function (stack, options, item, callback) {
|
|
|
359
371
|
}
|
|
360
372
|
|
|
361
373
|
// Parse out all of the frame and filename info
|
|
362
|
-
async.map(
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
374
|
+
async.map(
|
|
375
|
+
lines,
|
|
376
|
+
parseFrameLine.bind({
|
|
377
|
+
useSourceMaps: options.nodeSourceMaps,
|
|
378
|
+
diagnostic: item.diagnostic,
|
|
379
|
+
}),
|
|
380
|
+
function (err, frames) {
|
|
381
|
+
if (err) {
|
|
382
|
+
return callback(err);
|
|
383
|
+
}
|
|
384
|
+
frames.reverse();
|
|
385
|
+
async.filter(
|
|
386
|
+
frames,
|
|
387
|
+
function (frame, callback) {
|
|
388
|
+
callback(null, !!frame);
|
|
389
|
+
},
|
|
390
|
+
function (err, results) {
|
|
391
|
+
if (err) return callback(err);
|
|
392
|
+
gatherContexts(results, callback);
|
|
393
|
+
},
|
|
394
|
+
);
|
|
395
|
+
},
|
|
396
|
+
);
|
|
372
397
|
};
|