rollbar 2.24.0 → 2.25.1
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/pull_request_template.md +15 -6
- package/.github/workflows/ci.yml +1 -1
- package/dist/rollbar.js +54 -14
- 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 +54 -14
- 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 +54 -14
- 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 +54 -14
- 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/index.d.ts +83 -3
- package/package.json +4 -6
- package/src/api.js +6 -1
- package/src/browser/shim.js +8 -1
- package/src/browser/telemetry.js +6 -4
- package/src/browser/transforms.js +2 -2
- package/src/defaults.js +1 -1
- package/src/errorParser.js +2 -2
- package/src/server/parser.js +12 -14
- package/src/server/transforms.js +1 -1
- package/src/utility.js +37 -4
- package/test/browser.core.test.js +216 -126
- package/test/browser.rollbar.test.js +330 -244
- package/test/browser.transforms.test.js +43 -0
- package/test/react-native.rollbar.test.js +12 -8
- package/test/server.rollbar.test.js +6 -6
- package/test/server.transforms.test.js +52 -1
package/index.d.ts
CHANGED
|
@@ -40,6 +40,9 @@ declare namespace Rollbar {
|
|
|
40
40
|
) => void | Promise<TResult>;
|
|
41
41
|
export type MaybeError = Error | undefined | null;
|
|
42
42
|
export type Level = "debug" | "info" | "warning" | "error" | "critical";
|
|
43
|
+
/**
|
|
44
|
+
* {@link https://docs.rollbar.com/docs/rollbarjs-configuration-reference#reference}
|
|
45
|
+
*/
|
|
43
46
|
export interface Configuration {
|
|
44
47
|
accessToken?: string;
|
|
45
48
|
addErrorContext?: boolean;
|
|
@@ -52,7 +55,15 @@ declare namespace Rollbar {
|
|
|
52
55
|
captureUnhandledRejections?: boolean;
|
|
53
56
|
captureUsername?: boolean;
|
|
54
57
|
checkIgnore?: (isUncaught: boolean, args: LogArgument[], item: object) => boolean;
|
|
58
|
+
/**
|
|
59
|
+
* `codeVersion` takes precedence over `code_version`, if provided.
|
|
60
|
+
* `client.javascript.code_version` takes precedence over both top level properties.
|
|
61
|
+
*/
|
|
55
62
|
codeVersion?: string;
|
|
63
|
+
/**
|
|
64
|
+
* `codeVersion` takes precedence over `code_version`, if provided.
|
|
65
|
+
* `client.javascript.code_version` takes precedence over both top level properties.
|
|
66
|
+
*/
|
|
56
67
|
code_version?: string;
|
|
57
68
|
enabled?: boolean;
|
|
58
69
|
endpoint?: string;
|
|
@@ -77,7 +88,7 @@ declare namespace Rollbar {
|
|
|
77
88
|
nodeSourceMaps?: boolean;
|
|
78
89
|
onSendCallback?: (isUncaught: boolean, args: LogArgument[], item: object) => void;
|
|
79
90
|
overwriteScrubFields?: boolean;
|
|
80
|
-
payload?:
|
|
91
|
+
payload?: Payload;
|
|
81
92
|
reportLevel?: Level;
|
|
82
93
|
rewriteFilenamePatterns?: string[];
|
|
83
94
|
scrubFields?: string[];
|
|
@@ -89,7 +100,7 @@ declare namespace Rollbar {
|
|
|
89
100
|
stackTraceLimit?: number;
|
|
90
101
|
telemetryScrubber?: TelemetryScrubber;
|
|
91
102
|
timeout?: number;
|
|
92
|
-
transform?: (data: object) => void
|
|
103
|
+
transform?: (data: object, item: object) => void | Promise<void>;
|
|
93
104
|
transmit?: boolean;
|
|
94
105
|
uncaughtErrorLevel?: Level;
|
|
95
106
|
verbose?: boolean;
|
|
@@ -143,7 +154,7 @@ declare namespace Rollbar {
|
|
|
143
154
|
export type LocalsType = typeof Locals;
|
|
144
155
|
export type LocalsOptions = LocalsType | LocalsSettings;
|
|
145
156
|
export interface LocalsSettings {
|
|
146
|
-
|
|
157
|
+
module: LocalsType,
|
|
147
158
|
enabled?: boolean;
|
|
148
159
|
uncaughtOnly?: boolean;
|
|
149
160
|
depth?: number;
|
|
@@ -169,4 +180,73 @@ declare namespace Rollbar {
|
|
|
169
180
|
scrub?: ScrubType,
|
|
170
181
|
truncation?: TruncationType
|
|
171
182
|
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* @deprecated number is deprecated for this field
|
|
186
|
+
*/
|
|
187
|
+
export type DeprecatedNumber = number;
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* {@link https://docs.rollbar.com/docs/rollbarjs-configuration-reference#payload-1}
|
|
191
|
+
*/
|
|
192
|
+
export interface Payload {
|
|
193
|
+
person?: {
|
|
194
|
+
id: string | DeprecatedNumber;
|
|
195
|
+
username?: string;
|
|
196
|
+
email?: string;
|
|
197
|
+
[property: string]: any;
|
|
198
|
+
},
|
|
199
|
+
context?: any;
|
|
200
|
+
client?: {
|
|
201
|
+
javascript?: {
|
|
202
|
+
/**
|
|
203
|
+
* Version control number (i.e. git SHA) of the current revision. Used for linking filenames in stacktraces to GitHub.
|
|
204
|
+
* Note: for the purposes of nesting under the payload key, only code_version will correctly set the value in the final item.
|
|
205
|
+
* However, if you wish to set this code version at the top level of the configuration object rather than nested under
|
|
206
|
+
* the payload key, we will accept both codeVersion and code_version with codeVersion given preference if both happened
|
|
207
|
+
* to be defined. Furthermore, if code_version is nested under the payload key this will have the final preference over
|
|
208
|
+
* any value set at the top level.
|
|
209
|
+
*/
|
|
210
|
+
code_version?: string | DeprecatedNumber;
|
|
211
|
+
/**
|
|
212
|
+
* When true, the Rollbar service will attempt to find and apply source maps to all frames in the stack trace.
|
|
213
|
+
* @default false
|
|
214
|
+
*/
|
|
215
|
+
source_map_enabled?: boolean;
|
|
216
|
+
/**
|
|
217
|
+
* When true, the Rollbar service will attempt to apply source maps to frames even if they are missing column numbers.
|
|
218
|
+
* Works best when the minified javascript file is generated using newlines instead of semicolons.
|
|
219
|
+
* @default false
|
|
220
|
+
*/
|
|
221
|
+
guess_uncaught_frames?: boolean;
|
|
222
|
+
[property: string]: any;
|
|
223
|
+
}
|
|
224
|
+
[property: string]: any;
|
|
225
|
+
},
|
|
226
|
+
/**
|
|
227
|
+
* The environment that your code is running in.
|
|
228
|
+
* @default undefined
|
|
229
|
+
*/
|
|
230
|
+
environment?: string;
|
|
231
|
+
server?: {
|
|
232
|
+
/**
|
|
233
|
+
* @default master
|
|
234
|
+
*/
|
|
235
|
+
branch?: string;
|
|
236
|
+
/**
|
|
237
|
+
* The hostname of the machine that rendered the page.
|
|
238
|
+
*/
|
|
239
|
+
host?: string;
|
|
240
|
+
/**
|
|
241
|
+
* It is used in two different ways: `source maps`, and `source control`.
|
|
242
|
+
*
|
|
243
|
+
* If you are looking for more information on it please go to:
|
|
244
|
+
* {@link https://docs.rollbar.com/docs/source-maps}
|
|
245
|
+
* {@link https://docs.rollbar.com/docs/source-control}
|
|
246
|
+
*/
|
|
247
|
+
root?: string;
|
|
248
|
+
[property: string]: any;
|
|
249
|
+
},
|
|
250
|
+
[property: string]: any;
|
|
251
|
+
}
|
|
172
252
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rollbar",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.25.1",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "http://github.com/rollbar/rollbar.js"
|
|
@@ -11,14 +11,13 @@
|
|
|
11
11
|
"browser": "dist/rollbar.umd.min.js",
|
|
12
12
|
"types": "./index.d.ts",
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"async": "~
|
|
14
|
+
"async": "~3.2.3",
|
|
15
15
|
"console-polyfill": "0.3.0",
|
|
16
16
|
"error-stack-parser": "^2.0.4",
|
|
17
17
|
"json-stringify-safe": "~5.0.0",
|
|
18
18
|
"lru-cache": "~2.2.1",
|
|
19
19
|
"request-ip": "~2.0.1",
|
|
20
|
-
"source-map": "^0.5.7"
|
|
21
|
-
"uuid": "3.0.x"
|
|
20
|
+
"source-map": "^0.5.7"
|
|
22
21
|
},
|
|
23
22
|
"devDependencies": {
|
|
24
23
|
"babel-core": "^6.26.3",
|
|
@@ -66,7 +65,6 @@
|
|
|
66
65
|
"karma-sourcemap-loader": "^0.3.5",
|
|
67
66
|
"karma-webpack": "^4.0.2",
|
|
68
67
|
"mocha": "^7.1.2",
|
|
69
|
-
"mootools": "^1.5.1",
|
|
70
68
|
"natives": "^1.1.6",
|
|
71
69
|
"nock": "^11.9.1",
|
|
72
70
|
"node-libs-browser": "^0.5.2",
|
|
@@ -78,7 +76,7 @@
|
|
|
78
76
|
"strict-loader": "^1.2.0",
|
|
79
77
|
"time-grunt": "^1.0.0",
|
|
80
78
|
"vows": "^0.8.3",
|
|
81
|
-
"webpack": "^4.
|
|
79
|
+
"webpack": "^4.46.0"
|
|
82
80
|
},
|
|
83
81
|
"optionalDependencies": {
|
|
84
82
|
"decache": "^3.0.5"
|
package/src/api.js
CHANGED
|
@@ -47,7 +47,12 @@ function Api(options, transport, urllib, truncation, jsonBackup) {
|
|
|
47
47
|
Api.prototype.postItem = function(data, callback) {
|
|
48
48
|
var transportOptions = helpers.transportOptions(this.transportOptions, 'POST');
|
|
49
49
|
var payload = helpers.buildPayload(this.accessToken, data, this.jsonBackup);
|
|
50
|
-
|
|
50
|
+
var self = this;
|
|
51
|
+
|
|
52
|
+
// ensure the network request is scheduled after the current tick.
|
|
53
|
+
setTimeout(function() {
|
|
54
|
+
self.transport.post(self.accessToken, transportOptions, payload, callback);
|
|
55
|
+
}, 0);
|
|
51
56
|
};
|
|
52
57
|
|
|
53
58
|
/**
|
package/src/browser/shim.js
CHANGED
|
@@ -62,9 +62,16 @@ function setupShim(window, options) {
|
|
|
62
62
|
globals.captureUnhandledRejections(window, handler, true);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
function pageTelemetryEnabled(ai) {
|
|
66
|
+
if (typeof ai === 'object' && (ai.page === undefined || ai.page)) {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
|
|
65
72
|
var ai = options.autoInstrument;
|
|
66
73
|
if (options.enabled !== false) {
|
|
67
|
-
if (ai === undefined || ai === true || (
|
|
74
|
+
if (ai === undefined || ai === true || pageTelemetryEnabled(ai)) {
|
|
68
75
|
if (window.addEventListener) {
|
|
69
76
|
window.addEventListener('load', handler.captureLoad.bind(handler));
|
|
70
77
|
window.addEventListener('DOMContentLoaded', handler.captureDomContentLoaded.bind(handler));
|
package/src/browser/telemetry.js
CHANGED
|
@@ -403,8 +403,10 @@ Instrumenter.prototype.instrumentNetwork = function() {
|
|
|
403
403
|
// Test to ensure body is a Promise, which it should always be.
|
|
404
404
|
if (typeof body.then === 'function') {
|
|
405
405
|
body.then(function (text) {
|
|
406
|
-
if (self.isJsonContentType(metadata.response_content_type)) {
|
|
406
|
+
if (text && self.isJsonContentType(metadata.response_content_type)) {
|
|
407
407
|
metadata.response.body = self.scrubJson(text);
|
|
408
|
+
} else {
|
|
409
|
+
metadata.response.body = text;
|
|
408
410
|
}
|
|
409
411
|
});
|
|
410
412
|
} else {
|
|
@@ -729,16 +731,16 @@ Instrumenter.prototype.handleCspError = function(message) {
|
|
|
729
731
|
}
|
|
730
732
|
|
|
731
733
|
Instrumenter.prototype.deinstrumentContentSecurityPolicy = function() {
|
|
732
|
-
if (!('addEventListener' in this.
|
|
734
|
+
if (!('addEventListener' in this._document)) { return; }
|
|
733
735
|
|
|
734
736
|
this.removeListeners('contentsecuritypolicy');
|
|
735
737
|
};
|
|
736
738
|
|
|
737
739
|
Instrumenter.prototype.instrumentContentSecurityPolicy = function() {
|
|
738
|
-
if (!('addEventListener' in this.
|
|
740
|
+
if (!('addEventListener' in this._document)) { return; }
|
|
739
741
|
|
|
740
742
|
var cspHandler = this.handleCspEvent.bind(this);
|
|
741
|
-
this.addListener('contentsecuritypolicy', this.
|
|
743
|
+
this.addListener('contentsecuritypolicy', this._document, 'securitypolicyviolation', null, cspHandler, false);
|
|
742
744
|
};
|
|
743
745
|
|
|
744
746
|
Instrumenter.prototype.addListener = function(section, obj, type, altType, handler, capture) {
|
package/src/defaults.js
CHANGED
package/src/errorParser.js
CHANGED
|
@@ -64,11 +64,11 @@ function Stack(exception, skip) {
|
|
|
64
64
|
function parse(e, skip) {
|
|
65
65
|
var err = e;
|
|
66
66
|
|
|
67
|
-
if (err.nested) {
|
|
67
|
+
if (err.nested || err.cause) {
|
|
68
68
|
var traceChain = [];
|
|
69
69
|
while (err) {
|
|
70
70
|
traceChain.push(new Stack(err, skip));
|
|
71
|
-
err = err.nested;
|
|
71
|
+
err = err.nested || err.cause;
|
|
72
72
|
|
|
73
73
|
skip = 0; // Only apply skip value to primary error
|
|
74
74
|
}
|
package/src/server/parser.js
CHANGED
|
@@ -181,7 +181,7 @@ function shouldReadFrameFile(frameFilename, callback) {
|
|
|
181
181
|
isCached = !!cache.get(frameFilename);
|
|
182
182
|
isPending = !!pendingReads[frameFilename];
|
|
183
183
|
|
|
184
|
-
callback(isValidFilename && !isCached && !isPending);
|
|
184
|
+
callback(null, isValidFilename && !isCached && !isPending);
|
|
185
185
|
}
|
|
186
186
|
|
|
187
187
|
|
|
@@ -201,19 +201,13 @@ function readFileLines(filename, callback) {
|
|
|
201
201
|
}
|
|
202
202
|
}
|
|
203
203
|
|
|
204
|
-
|
|
205
|
-
/* Older versions of node do not have fs.exists so we implement our own */
|
|
206
204
|
function checkFileExists(filename, callback) {
|
|
207
205
|
if (stackTrace.sourceContent(filename)) {
|
|
208
|
-
return callback(true);
|
|
209
|
-
}
|
|
210
|
-
if (fs.exists !== undefined) {
|
|
211
|
-
fs.exists(filename, callback);
|
|
212
|
-
} else {
|
|
213
|
-
fs.stat(filename, function (err) {
|
|
214
|
-
callback(!err);
|
|
215
|
-
});
|
|
206
|
+
return callback(null, true);
|
|
216
207
|
}
|
|
208
|
+
fs.stat(filename, function (err) {
|
|
209
|
+
callback(null, !err);
|
|
210
|
+
});
|
|
217
211
|
}
|
|
218
212
|
|
|
219
213
|
|
|
@@ -226,7 +220,9 @@ function gatherContexts(frames, callback) {
|
|
|
226
220
|
}
|
|
227
221
|
});
|
|
228
222
|
|
|
229
|
-
async.filter(frameFilenames, shouldReadFrameFile, function (results) {
|
|
223
|
+
async.filter(frameFilenames, shouldReadFrameFile, function (err, results) {
|
|
224
|
+
if (err) return callback(err);
|
|
225
|
+
|
|
230
226
|
var tempFileCache;
|
|
231
227
|
|
|
232
228
|
tempFileCache = {};
|
|
@@ -270,7 +266,8 @@ function gatherContexts(frames, callback) {
|
|
|
270
266
|
callback(null);
|
|
271
267
|
}
|
|
272
268
|
|
|
273
|
-
async.filter(results, checkFileExists, function (filenames) {
|
|
269
|
+
async.filter(results, checkFileExists, function (err, filenames) {
|
|
270
|
+
if (err) return callback(err);
|
|
274
271
|
async.each(filenames, gatherFileData, function (err) {
|
|
275
272
|
if (err) {
|
|
276
273
|
return callback(err);
|
|
@@ -367,7 +364,8 @@ exports.parseStack = function (stack, options, item, callback) {
|
|
|
367
364
|
return callback(err);
|
|
368
365
|
}
|
|
369
366
|
frames.reverse();
|
|
370
|
-
async.filter(frames, function (frame, callback) { callback(!!frame); }, function (results) {
|
|
367
|
+
async.filter(frames, function (frame, callback) { callback(null, !!frame); }, function (err, results) {
|
|
368
|
+
if (err) return callback(err);
|
|
371
369
|
gatherContexts(results, callback);
|
|
372
370
|
});
|
|
373
371
|
});
|
package/src/server/transforms.js
CHANGED
package/src/utility.js
CHANGED
|
@@ -398,6 +398,37 @@ function wrapCallback(logger, f) {
|
|
|
398
398
|
};
|
|
399
399
|
}
|
|
400
400
|
|
|
401
|
+
function nonCircularClone(obj) {
|
|
402
|
+
var seen = [obj];
|
|
403
|
+
|
|
404
|
+
function clone(obj, seen) {
|
|
405
|
+
var value, name, newSeen, result = {};
|
|
406
|
+
|
|
407
|
+
try {
|
|
408
|
+
for (name in obj) {
|
|
409
|
+
value = obj[name];
|
|
410
|
+
|
|
411
|
+
if (value && (isType(value, 'object') || isType(value, 'array'))) {
|
|
412
|
+
if (seen.includes(value)) {
|
|
413
|
+
result[name] = 'Removed circular reference: ' + typeName(value);
|
|
414
|
+
} else {
|
|
415
|
+
newSeen = seen.slice();
|
|
416
|
+
newSeen.push(value);
|
|
417
|
+
result[name] = clone(value, newSeen);
|
|
418
|
+
}
|
|
419
|
+
continue;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
result[name] = value;
|
|
423
|
+
}
|
|
424
|
+
} catch (e) {
|
|
425
|
+
result = 'Failed cloning custom data: ' + e.message;
|
|
426
|
+
}
|
|
427
|
+
return result;
|
|
428
|
+
}
|
|
429
|
+
return clone(obj, seen);
|
|
430
|
+
}
|
|
431
|
+
|
|
401
432
|
function createItem(args, logger, notifier, requestKeys, lambdaContext) {
|
|
402
433
|
var message, err, custom, callback, request;
|
|
403
434
|
var arg;
|
|
@@ -455,10 +486,12 @@ function createItem(args, logger, notifier, requestKeys, lambdaContext) {
|
|
|
455
486
|
}
|
|
456
487
|
}
|
|
457
488
|
|
|
489
|
+
// if custom is an array this turns it into an object with integer keys
|
|
490
|
+
if (custom) custom = nonCircularClone(custom);
|
|
491
|
+
|
|
458
492
|
if (extraArgs.length > 0) {
|
|
459
|
-
|
|
460
|
-
custom =
|
|
461
|
-
custom.extraArgs = extraArgs;
|
|
493
|
+
if (!custom) custom = nonCircularClone({});
|
|
494
|
+
custom.extraArgs = nonCircularClone(extraArgs);
|
|
462
495
|
}
|
|
463
496
|
|
|
464
497
|
var item = {
|
|
@@ -503,7 +536,7 @@ function addErrorContext(item, errors) {
|
|
|
503
536
|
try {
|
|
504
537
|
for (var i = 0; i < errors.length; ++i) {
|
|
505
538
|
if (errors[i].hasOwnProperty('rollbarContext')) {
|
|
506
|
-
custom = merge(custom, errors[i].rollbarContext);
|
|
539
|
+
custom = merge(custom, nonCircularClone(errors[i].rollbarContext));
|
|
507
540
|
contextAdded = true;
|
|
508
541
|
}
|
|
509
542
|
}
|