rollbar 2.26.3 → 3.0.0-alpha.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/.cursor/rules/guidelines.mdc +154 -0
- package/.github/workflows/ci.yml +32 -12
- package/.lgtm.yml +7 -7
- package/.prettierignore +18 -0
- package/.vscode/settings.json +39 -0
- package/CHANGELOG.md +121 -35
- package/CLAUDE.md +201 -0
- package/Gruntfile.js +101 -48
- package/Makefile +3 -3
- package/README.md +2 -4
- package/SECURITY.md +5 -0
- package/babel.config.json +9 -0
- package/bower.json +1 -3
- package/codex.md +148 -0
- package/defaults.js +17 -5
- package/dist/plugins/jquery.min.js +1 -1
- package/dist/rollbar.js +18748 -5375
- package/dist/rollbar.js.map +1 -1
- package/dist/rollbar.min.js +2 -1
- package/dist/rollbar.min.js.LICENSE.txt +1 -0
- package/dist/rollbar.min.js.map +1 -1
- package/dist/rollbar.named-amd.js +19368 -6000
- package/dist/rollbar.named-amd.js.map +1 -1
- package/dist/rollbar.named-amd.min.js +3 -1
- package/dist/rollbar.named-amd.min.js.LICENSE.txt +1 -0
- package/dist/rollbar.named-amd.min.js.map +1 -1
- package/dist/rollbar.noconflict.umd.js +18749 -5380
- package/dist/rollbar.noconflict.umd.js.map +1 -1
- package/dist/rollbar.noconflict.umd.min.js +3 -1
- package/dist/rollbar.noconflict.umd.min.js.LICENSE.txt +1 -0
- package/dist/rollbar.noconflict.umd.min.js.map +1 -1
- package/dist/rollbar.snippet.js +1 -1
- package/dist/rollbar.umd.js +19367 -6000
- package/dist/rollbar.umd.js.map +1 -1
- package/dist/rollbar.umd.min.js +3 -1
- package/dist/rollbar.umd.min.js.LICENSE.txt +1 -0
- 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/eslint.config.mjs +33 -0
- package/get_versions.js +33 -0
- package/index.d.ts +270 -231
- package/karma.conf.js +18 -27
- package/package.json +21 -21
- package/prettier.config.js +7 -0
- package/src/api.js +78 -14
- package/src/apiUtility.js +14 -11
- package/src/browser/core.js +138 -72
- 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/replay/defaults.js +71 -0
- package/src/browser/replay/recorder.js +193 -0
- package/src/browser/replay/replayMap.js +195 -0
- package/src/browser/rollbar.js +12 -8
- 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 -361
- package/src/browser/transforms.js +46 -27
- package/src/browser/transport/fetch.js +26 -14
- package/src/browser/transport/xhr.js +41 -14
- package/src/browser/transport.js +93 -33
- 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 +133 -40
- 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 +72 -21
- 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 +135 -56
- 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 +162 -33
- package/src/tracing/context.js +24 -0
- package/src/tracing/contextManager.js +37 -0
- package/src/tracing/defaults.js +7 -0
- package/src/tracing/exporter.js +188 -0
- package/src/tracing/hrtime.js +98 -0
- package/src/tracing/id.js +24 -0
- package/src/tracing/session.js +55 -0
- package/src/tracing/span.js +92 -0
- package/src/tracing/spanProcessor.js +15 -0
- package/src/tracing/tracer.js +46 -0
- package/src/tracing/tracing.js +89 -0
- 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 +123 -52
- package/test/api.test.js +88 -41
- package/test/apiUtility.test.js +48 -50
- package/test/browser.core.test.js +142 -141
- package/test/browser.domUtility.test.js +53 -36
- package/test/browser.predicates.test.js +14 -14
- package/test/browser.replay.recorder.test.js +416 -0
- package/test/browser.rollbar.test.js +655 -515
- package/test/browser.telemetry.test.js +46 -39
- package/test/browser.transforms.test.js +164 -139
- package/test/browser.transport.test.js +59 -50
- package/test/browser.url.test.js +13 -12
- package/test/fixtures/locals.fixtures.js +245 -126
- package/test/fixtures/replay/index.js +20 -0
- package/test/fixtures/replay/payloads.fixtures.js +229 -0
- package/test/fixtures/replay/rrwebEvents.fixtures.js +251 -0
- package/test/fixtures/replay/rrwebSyntheticEvents.fixtures.js +328 -0
- package/test/notifier.test.js +91 -79
- package/test/predicates.test.js +261 -215
- package/test/queue.test.js +231 -215
- package/test/rateLimiter.test.js +51 -43
- package/test/react-native.rollbar.test.js +150 -116
- package/test/react-native.transforms.test.js +23 -25
- package/test/react-native.transport.test.js +26 -14
- package/test/replay/index.js +2 -0
- package/test/replay/integration/api.spans.test.js +136 -0
- package/test/replay/integration/e2e.test.js +228 -0
- package/test/replay/integration/index.js +9 -0
- package/test/replay/integration/queue.replayMap.test.js +332 -0
- package/test/replay/integration/replayMap.test.js +163 -0
- package/test/replay/integration/sessionRecording.test.js +390 -0
- package/test/replay/unit/api.postSpans.test.js +150 -0
- package/test/replay/unit/index.js +7 -0
- package/test/replay/unit/queue.replayMap.test.js +225 -0
- package/test/replay/unit/replayMap.test.js +348 -0
- package/test/replay/util/index.js +5 -0
- package/test/replay/util/mockRecordFn.js +80 -0
- package/test/server.lambda.mocha.test.mjs +172 -0
- package/test/server.locals.constructor.mocha.test.mjs +80 -0
- package/test/server.locals.error-handling.mocha.test.mjs +387 -0
- package/test/server.locals.merge.mocha.test.mjs +267 -0
- package/test/server.locals.test-utils.mjs +114 -0
- package/test/server.parser.mocha.test.mjs +87 -0
- package/test/server.predicates.mocha.test.mjs +63 -0
- package/test/server.rollbar.constructor.mocha.test.mjs +199 -0
- package/test/server.rollbar.handlers.mocha.test.mjs +253 -0
- package/test/server.rollbar.logging.mocha.test.mjs +326 -0
- package/test/server.rollbar.misc.mocha.test.mjs +44 -0
- package/test/server.rollbar.test-utils.mjs +57 -0
- package/test/server.telemetry.mocha.test.mjs +377 -0
- package/test/server.transforms.data.mocha.test.mjs +163 -0
- package/test/server.transforms.error.mocha.test.mjs +199 -0
- package/test/server.transforms.request.mocha.test.mjs +208 -0
- package/test/server.transforms.scrub.mocha.test.mjs +140 -0
- package/test/server.transforms.sourcemaps.mocha.test.mjs +122 -0
- package/test/server.transforms.test-utils.mjs +62 -0
- package/test/server.transport.mocha.test.mjs +269 -0
- package/test/telemetry.test.js +178 -38
- package/test/tracing/contextManager.test.js +28 -0
- package/test/tracing/exporter.toPayload.test.js +400 -0
- package/test/tracing/id.test.js +24 -0
- package/test/tracing/span.test.js +183 -0
- package/test/tracing/spanProcessor.test.js +73 -0
- package/test/tracing/tracing.test.js +105 -0
- package/test/transforms.test.js +70 -68
- package/test/truncation.test.js +57 -55
- package/test/utility.test.js +310 -228
- package/webpack.config.js +36 -70
- package/.eslintignore +0 -7
- package/.gitmodules +0 -3
- package/test/server.lambda.test.js +0 -177
- package/test/server.locals.test.js +0 -841
- package/test/server.parser.test.js +0 -72
- package/test/server.predicates.test.js +0 -89
- package/test/server.rollbar.test.js +0 -676
- package/test/server.telemetry.test.js +0 -318
- package/test/server.transforms.test.js +0 -1099
- package/test/server.transport.test.js +0 -201
package/src/utility.js
CHANGED
|
@@ -8,14 +8,15 @@ function setupJSON(polyfillJSON) {
|
|
|
8
8
|
|
|
9
9
|
if (isDefined(JSON)) {
|
|
10
10
|
// If polyfill is provided, prefer it over existing non-native shims.
|
|
11
|
-
if(polyfillJSON) {
|
|
11
|
+
if (polyfillJSON) {
|
|
12
12
|
if (isNativeFunction(JSON.stringify)) {
|
|
13
13
|
RollbarJSON.stringify = JSON.stringify;
|
|
14
14
|
}
|
|
15
15
|
if (isNativeFunction(JSON.parse)) {
|
|
16
16
|
RollbarJSON.parse = JSON.parse;
|
|
17
17
|
}
|
|
18
|
-
} else {
|
|
18
|
+
} else {
|
|
19
|
+
// else accept any interface that is present.
|
|
19
20
|
if (isFunction(JSON.stringify)) {
|
|
20
21
|
RollbarJSON.stringify = JSON.stringify;
|
|
21
22
|
}
|
|
@@ -65,7 +66,10 @@ function typeName(x) {
|
|
|
65
66
|
if (x instanceof Error) {
|
|
66
67
|
return 'error';
|
|
67
68
|
}
|
|
68
|
-
return
|
|
69
|
+
return {}.toString
|
|
70
|
+
.call(x)
|
|
71
|
+
.match(/\s([a-zA-Z]+)/)[1]
|
|
72
|
+
.toLowerCase();
|
|
69
73
|
}
|
|
70
74
|
|
|
71
75
|
/* isFunction - a convenience function for checking if a value is a function
|
|
@@ -84,7 +88,8 @@ function isFunction(f) {
|
|
|
84
88
|
*/
|
|
85
89
|
function isNativeFunction(f) {
|
|
86
90
|
var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
|
|
87
|
-
var funcMatchString = Function.prototype.toString
|
|
91
|
+
var funcMatchString = Function.prototype.toString
|
|
92
|
+
.call(Object.prototype.hasOwnProperty)
|
|
88
93
|
.replace(reRegExpChar, '\\$&')
|
|
89
94
|
.replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?');
|
|
90
95
|
var reIsNative = RegExp('^' + funcMatchString + '$');
|
|
@@ -95,7 +100,7 @@ function isNativeFunction(f) {
|
|
|
95
100
|
*
|
|
96
101
|
* @param value - any value
|
|
97
102
|
* @returns true is value is an object function is an object)
|
|
98
|
-
*/
|
|
103
|
+
*/
|
|
99
104
|
function isObject(value) {
|
|
100
105
|
var type = typeof value;
|
|
101
106
|
return value != null && (type == 'object' || type == 'function');
|
|
@@ -105,9 +110,9 @@ function isObject(value) {
|
|
|
105
110
|
*
|
|
106
111
|
* @param value - any value
|
|
107
112
|
* @returns true if value is a string
|
|
108
|
-
*/
|
|
113
|
+
*/
|
|
109
114
|
function isString(value) {
|
|
110
|
-
return typeof value === 'string' || value instanceof String
|
|
115
|
+
return typeof value === 'string' || value instanceof String;
|
|
111
116
|
}
|
|
112
117
|
|
|
113
118
|
/**
|
|
@@ -116,7 +121,7 @@ function isString(value) {
|
|
|
116
121
|
* @param {*} n - any value
|
|
117
122
|
* @returns true if value is a finite number
|
|
118
123
|
*/
|
|
119
|
-
|
|
124
|
+
function isFiniteNumber(n) {
|
|
120
125
|
return Number.isFinite(n);
|
|
121
126
|
}
|
|
122
127
|
|
|
@@ -139,7 +144,7 @@ function isDefined(u) {
|
|
|
139
144
|
*/
|
|
140
145
|
function isIterable(i) {
|
|
141
146
|
var type = typeName(i);
|
|
142
|
-
return
|
|
147
|
+
return type === 'object' || type === 'array';
|
|
143
148
|
}
|
|
144
149
|
|
|
145
150
|
/*
|
|
@@ -162,6 +167,15 @@ function isPromise(p) {
|
|
|
162
167
|
return isObject(p) && isType(p.then, 'function');
|
|
163
168
|
}
|
|
164
169
|
|
|
170
|
+
/**
|
|
171
|
+
* isBrowser - a convenience function for checking if the code is running in a browser
|
|
172
|
+
*
|
|
173
|
+
* @returns true if the code is running in a browser environment
|
|
174
|
+
*/
|
|
175
|
+
function isBrowser() {
|
|
176
|
+
return typeof window !== 'undefined';
|
|
177
|
+
}
|
|
178
|
+
|
|
165
179
|
function redact() {
|
|
166
180
|
return '********';
|
|
167
181
|
}
|
|
@@ -169,11 +183,14 @@ function redact() {
|
|
|
169
183
|
// from http://stackoverflow.com/a/8809472/1138191
|
|
170
184
|
function uuid4() {
|
|
171
185
|
var d = now();
|
|
172
|
-
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
186
|
+
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(
|
|
187
|
+
/[xy]/g,
|
|
188
|
+
function (c) {
|
|
189
|
+
var r = (d + Math.random() * 16) % 16 | 0;
|
|
190
|
+
d = Math.floor(d / 16);
|
|
191
|
+
return (c === 'x' ? r : (r & 0x7) | 0x8).toString(16);
|
|
192
|
+
},
|
|
193
|
+
);
|
|
177
194
|
return uuid;
|
|
178
195
|
}
|
|
179
196
|
|
|
@@ -182,7 +199,7 @@ var LEVELS = {
|
|
|
182
199
|
info: 1,
|
|
183
200
|
warning: 2,
|
|
184
201
|
error: 3,
|
|
185
|
-
critical: 4
|
|
202
|
+
critical: 4,
|
|
186
203
|
};
|
|
187
204
|
|
|
188
205
|
function sanitizeUrl(url) {
|
|
@@ -216,16 +233,18 @@ var parseUriOptions = {
|
|
|
216
233
|
'directory',
|
|
217
234
|
'file',
|
|
218
235
|
'query',
|
|
219
|
-
'anchor'
|
|
236
|
+
'anchor',
|
|
220
237
|
],
|
|
221
238
|
q: {
|
|
222
239
|
name: 'queryKey',
|
|
223
|
-
parser: /(?:^|&)([^&=]*)=?([^&]*)/g
|
|
240
|
+
parser: /(?:^|&)([^&=]*)=?([^&]*)/g,
|
|
224
241
|
},
|
|
225
242
|
parser: {
|
|
226
|
-
strict:
|
|
227
|
-
|
|
228
|
-
|
|
243
|
+
strict:
|
|
244
|
+
/^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
|
|
245
|
+
loose:
|
|
246
|
+
/^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/,
|
|
247
|
+
},
|
|
229
248
|
};
|
|
230
249
|
|
|
231
250
|
function parseUri(str) {
|
|
@@ -270,11 +289,11 @@ function addParamsAndAccessTokenToPath(accessToken, options, params) {
|
|
|
270
289
|
var p;
|
|
271
290
|
if (qs !== -1 && (h === -1 || h > qs)) {
|
|
272
291
|
p = options.path;
|
|
273
|
-
options.path = p.substring(0,qs) + query + '&' + p.substring(qs+1);
|
|
292
|
+
options.path = p.substring(0, qs) + query + '&' + p.substring(qs + 1);
|
|
274
293
|
} else {
|
|
275
294
|
if (h !== -1) {
|
|
276
295
|
p = options.path;
|
|
277
|
-
options.path = p.substring(0,h) + query + p.substring(h);
|
|
296
|
+
options.path = p.substring(0, h) + query + p.substring(h);
|
|
278
297
|
} else {
|
|
279
298
|
options.path = options.path + query;
|
|
280
299
|
}
|
|
@@ -320,7 +339,7 @@ function stringify(obj, backup) {
|
|
|
320
339
|
error = jsonError;
|
|
321
340
|
}
|
|
322
341
|
}
|
|
323
|
-
return {error: error, value: value};
|
|
342
|
+
return { error: error, value: value };
|
|
324
343
|
}
|
|
325
344
|
|
|
326
345
|
function maxByteSize(string) {
|
|
@@ -338,11 +357,14 @@ function maxByteSize(string) {
|
|
|
338
357
|
|
|
339
358
|
for (var i = 0; i < length; i++) {
|
|
340
359
|
var code = string.charCodeAt(i);
|
|
341
|
-
if (code < 128) {
|
|
360
|
+
if (code < 128) {
|
|
361
|
+
// up to 7 bits
|
|
342
362
|
count = count + 1;
|
|
343
|
-
} else if (code < 2048) {
|
|
363
|
+
} else if (code < 2048) {
|
|
364
|
+
// up to 11 bits
|
|
344
365
|
count = count + 2;
|
|
345
|
-
} else if (code < 65536) {
|
|
366
|
+
} else if (code < 65536) {
|
|
367
|
+
// up to 16 bits
|
|
346
368
|
count = count + 3;
|
|
347
369
|
}
|
|
348
370
|
}
|
|
@@ -357,7 +379,7 @@ function jsonParse(s) {
|
|
|
357
379
|
} catch (e) {
|
|
358
380
|
error = e;
|
|
359
381
|
}
|
|
360
|
-
return {error: error, value: value};
|
|
382
|
+
return { error: error, value: value };
|
|
361
383
|
}
|
|
362
384
|
|
|
363
385
|
function makeUnhandledStackInfo(
|
|
@@ -368,28 +390,36 @@ function makeUnhandledStackInfo(
|
|
|
368
390
|
error,
|
|
369
391
|
mode,
|
|
370
392
|
backupMessage,
|
|
371
|
-
errorParser
|
|
393
|
+
errorParser,
|
|
372
394
|
) {
|
|
373
395
|
var location = {
|
|
374
396
|
url: url || '',
|
|
375
397
|
line: lineno,
|
|
376
|
-
column: colno
|
|
398
|
+
column: colno,
|
|
377
399
|
};
|
|
378
400
|
location.func = errorParser.guessFunctionName(location.url, location.line);
|
|
379
401
|
location.context = errorParser.gatherContext(location.url, location.line);
|
|
380
|
-
var href =
|
|
381
|
-
|
|
402
|
+
var href =
|
|
403
|
+
typeof document !== 'undefined' &&
|
|
404
|
+
document &&
|
|
405
|
+
document.location &&
|
|
406
|
+
document.location.href;
|
|
407
|
+
var useragent =
|
|
408
|
+
typeof window !== 'undefined' &&
|
|
409
|
+
window &&
|
|
410
|
+
window.navigator &&
|
|
411
|
+
window.navigator.userAgent;
|
|
382
412
|
return {
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
413
|
+
mode: mode,
|
|
414
|
+
message: error ? String(error) : message || backupMessage,
|
|
415
|
+
url: href,
|
|
416
|
+
stack: [location],
|
|
417
|
+
useragent: useragent,
|
|
388
418
|
};
|
|
389
419
|
}
|
|
390
420
|
|
|
391
421
|
function wrapCallback(logger, f) {
|
|
392
|
-
return function(err, resp) {
|
|
422
|
+
return function (err, resp) {
|
|
393
423
|
try {
|
|
394
424
|
f(err, resp);
|
|
395
425
|
} catch (e) {
|
|
@@ -402,7 +432,10 @@ function nonCircularClone(obj) {
|
|
|
402
432
|
var seen = [obj];
|
|
403
433
|
|
|
404
434
|
function clone(obj, seen) {
|
|
405
|
-
var value,
|
|
435
|
+
var value,
|
|
436
|
+
name,
|
|
437
|
+
newSeen,
|
|
438
|
+
result = {};
|
|
406
439
|
|
|
407
440
|
try {
|
|
408
441
|
for (name in obj) {
|
|
@@ -445,7 +478,7 @@ function createItem(args, logger, notifier, requestKeys, lambdaContext) {
|
|
|
445
478
|
case 'undefined':
|
|
446
479
|
break;
|
|
447
480
|
case 'string':
|
|
448
|
-
message ? extraArgs.push(arg) : message = arg;
|
|
481
|
+
message ? extraArgs.push(arg) : (message = arg);
|
|
449
482
|
break;
|
|
450
483
|
case 'function':
|
|
451
484
|
callback = wrapCallback(logger, arg);
|
|
@@ -456,12 +489,15 @@ function createItem(args, logger, notifier, requestKeys, lambdaContext) {
|
|
|
456
489
|
case 'error':
|
|
457
490
|
case 'domexception':
|
|
458
491
|
case 'exception': // Firefox Exception type
|
|
459
|
-
err ? extraArgs.push(arg) : err = arg;
|
|
492
|
+
err ? extraArgs.push(arg) : (err = arg);
|
|
460
493
|
break;
|
|
461
494
|
case 'object':
|
|
462
495
|
case 'array':
|
|
463
|
-
if (
|
|
464
|
-
|
|
496
|
+
if (
|
|
497
|
+
arg instanceof Error ||
|
|
498
|
+
(typeof DOMException !== 'undefined' && arg instanceof DOMException)
|
|
499
|
+
) {
|
|
500
|
+
err ? extraArgs.push(arg) : (err = arg);
|
|
465
501
|
break;
|
|
466
502
|
}
|
|
467
503
|
if (requestKeys && typ === 'object' && !request) {
|
|
@@ -475,11 +511,14 @@ function createItem(args, logger, notifier, requestKeys, lambdaContext) {
|
|
|
475
511
|
break;
|
|
476
512
|
}
|
|
477
513
|
}
|
|
478
|
-
custom ? extraArgs.push(arg) : custom = arg;
|
|
514
|
+
custom ? extraArgs.push(arg) : (custom = arg);
|
|
479
515
|
break;
|
|
480
516
|
default:
|
|
481
|
-
if (
|
|
482
|
-
|
|
517
|
+
if (
|
|
518
|
+
arg instanceof Error ||
|
|
519
|
+
(typeof DOMException !== 'undefined' && arg instanceof DOMException)
|
|
520
|
+
) {
|
|
521
|
+
err ? extraArgs.push(arg) : (err = arg);
|
|
483
522
|
break;
|
|
484
523
|
}
|
|
485
524
|
extraArgs.push(arg);
|
|
@@ -502,9 +541,11 @@ function createItem(args, logger, notifier, requestKeys, lambdaContext) {
|
|
|
502
541
|
callback: callback,
|
|
503
542
|
notifier: notifier,
|
|
504
543
|
diagnostic: diagnostic,
|
|
505
|
-
uuid: uuid4()
|
|
544
|
+
uuid: uuid4(),
|
|
506
545
|
};
|
|
507
546
|
|
|
547
|
+
item.data = item.data || {};
|
|
548
|
+
|
|
508
549
|
setCustomItemKeys(item, custom);
|
|
509
550
|
|
|
510
551
|
if (requestKeys && request) {
|
|
@@ -550,7 +591,14 @@ function addErrorContext(item, errors) {
|
|
|
550
591
|
}
|
|
551
592
|
}
|
|
552
593
|
|
|
553
|
-
var TELEMETRY_TYPES = [
|
|
594
|
+
var TELEMETRY_TYPES = [
|
|
595
|
+
'log',
|
|
596
|
+
'network',
|
|
597
|
+
'dom',
|
|
598
|
+
'navigation',
|
|
599
|
+
'error',
|
|
600
|
+
'manual',
|
|
601
|
+
];
|
|
554
602
|
var TELEMETRY_LEVELS = ['critical', 'error', 'warning', 'info', 'debug'];
|
|
555
603
|
|
|
556
604
|
function arrayIncludes(arr, val) {
|
|
@@ -589,12 +637,32 @@ function createTelemetryEvent(args) {
|
|
|
589
637
|
var event = {
|
|
590
638
|
type: type || 'manual',
|
|
591
639
|
metadata: metadata || {},
|
|
592
|
-
level: level
|
|
640
|
+
level: level,
|
|
593
641
|
};
|
|
594
642
|
|
|
595
643
|
return event;
|
|
596
644
|
}
|
|
597
645
|
|
|
646
|
+
function addItemAttributes(itemData, attributes) {
|
|
647
|
+
itemData.attributes = itemData.attributes || [];
|
|
648
|
+
for (const a of attributes) {
|
|
649
|
+
if (a.value === undefined) {
|
|
650
|
+
continue;
|
|
651
|
+
}
|
|
652
|
+
itemData.attributes.push(a);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
function getItemAttribute(itemData, key) {
|
|
657
|
+
const attributes = itemData.attributes || [];
|
|
658
|
+
for (let i = 0; i < attributes.length; ++i) {
|
|
659
|
+
if (attributes[i].key === key) {
|
|
660
|
+
return attributes[i].value;
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
return undefined;
|
|
664
|
+
}
|
|
665
|
+
|
|
598
666
|
/*
|
|
599
667
|
* get - given an obj/array and a keypath, return the value at that keypath or
|
|
600
668
|
* undefined if not possible.
|
|
@@ -639,7 +707,7 @@ function set(obj, path, value) {
|
|
|
639
707
|
temp[keys[i]] = temp[keys[i]] || {};
|
|
640
708
|
temp = temp[keys[i]];
|
|
641
709
|
}
|
|
642
|
-
temp[keys[len-1]] = value;
|
|
710
|
+
temp[keys[len - 1]] = value;
|
|
643
711
|
obj[keys[0]] = replacement;
|
|
644
712
|
} catch (e) {
|
|
645
713
|
return;
|
|
@@ -730,12 +798,12 @@ function handleOptions(current, input, payload, logger) {
|
|
|
730
798
|
}
|
|
731
799
|
|
|
732
800
|
function updateDeprecatedOptions(options, logger) {
|
|
733
|
-
if(options.hostWhiteList && !options.hostSafeList) {
|
|
801
|
+
if (options.hostWhiteList && !options.hostSafeList) {
|
|
734
802
|
options.hostSafeList = options.hostWhiteList;
|
|
735
803
|
options.hostWhiteList = undefined;
|
|
736
804
|
logger && logger.log('hostWhiteList is deprecated. Use hostSafeList.');
|
|
737
805
|
}
|
|
738
|
-
if(options.hostBlackList && !options.hostBlockList) {
|
|
806
|
+
if (options.hostBlackList && !options.hostBlockList) {
|
|
739
807
|
options.hostBlockList = options.hostBlackList;
|
|
740
808
|
options.hostBlackList = undefined;
|
|
741
809
|
logger && logger.log('hostBlackList is deprecated. Use hostBlockList.');
|
|
@@ -748,6 +816,8 @@ module.exports = {
|
|
|
748
816
|
createItem: createItem,
|
|
749
817
|
addErrorContext: addErrorContext,
|
|
750
818
|
createTelemetryEvent: createTelemetryEvent,
|
|
819
|
+
addItemAttributes: addItemAttributes,
|
|
820
|
+
getItemAttribute: getItemAttribute,
|
|
751
821
|
filterIp: filterIp,
|
|
752
822
|
formatArgsAsString: formatArgsAsString,
|
|
753
823
|
formatUrl: formatUrl,
|
|
@@ -762,6 +832,7 @@ module.exports = {
|
|
|
762
832
|
isString: isString,
|
|
763
833
|
isType: isType,
|
|
764
834
|
isPromise: isPromise,
|
|
835
|
+
isBrowser: isBrowser,
|
|
765
836
|
jsonParse: jsonParse,
|
|
766
837
|
LEVELS: LEVELS,
|
|
767
838
|
makeUnhandledStackInfo: makeUnhandledStackInfo,
|
|
@@ -775,5 +846,5 @@ module.exports = {
|
|
|
775
846
|
stringify: stringify,
|
|
776
847
|
maxByteSize: maxByteSize,
|
|
777
848
|
typeName: typeName,
|
|
778
|
-
uuid4: uuid4
|
|
849
|
+
uuid4: uuid4,
|
|
779
850
|
};
|
package/test/api.test.js
CHANGED
|
@@ -3,21 +3,21 @@
|
|
|
3
3
|
/* globals it */
|
|
4
4
|
/* globals sinon */
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
import API from '../src/api.js';
|
|
7
|
+
import utility from '../src/utility.js';
|
|
8
8
|
utility.setupJSON();
|
|
9
9
|
|
|
10
10
|
function TestTransportGenerator() {
|
|
11
|
-
var TestTransport = function(callbackError, callbackResponse) {
|
|
11
|
+
var TestTransport = function (callbackError, callbackResponse) {
|
|
12
12
|
this.postArgs = [];
|
|
13
13
|
this.callbackError = callbackError;
|
|
14
14
|
this.callbackResponse = callbackResponse;
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
-
TestTransport.prototype.post = function() {
|
|
17
|
+
TestTransport.prototype.post = function () {
|
|
18
18
|
var args = arguments;
|
|
19
19
|
this.postArgs.push(args);
|
|
20
|
-
var callback = args[args.length-1];
|
|
20
|
+
var callback = args[args.length - 1];
|
|
21
21
|
if (typeof callback === 'function') {
|
|
22
22
|
callback(this.callbackError, this.callbackResponse);
|
|
23
23
|
}
|
|
@@ -26,18 +26,17 @@ function TestTransportGenerator() {
|
|
|
26
26
|
return TestTransport;
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
describe('Api()', function() {
|
|
30
|
-
it('use the defaults if no custom endpoint is given', function(done) {
|
|
29
|
+
describe('Api()', function () {
|
|
30
|
+
it('use the defaults if no custom endpoint is given', function (done) {
|
|
31
31
|
var transport = new (TestTransportGenerator())();
|
|
32
32
|
var url = {
|
|
33
|
-
parse: function(e) {
|
|
33
|
+
parse: function (e) {
|
|
34
34
|
expect(false).to.be.ok();
|
|
35
|
-
}
|
|
35
|
+
},
|
|
36
36
|
};
|
|
37
|
-
var backup = null;
|
|
38
37
|
var accessToken = 'abc123';
|
|
39
|
-
var options = {accessToken: accessToken};
|
|
40
|
-
var api = new API(options, transport, url
|
|
38
|
+
var options = { accessToken: accessToken };
|
|
39
|
+
var api = new API(options, transport, url);
|
|
41
40
|
// I know this is testing internal state but it
|
|
42
41
|
// is the most expedient way to do this
|
|
43
42
|
expect(api.accessToken).to.eql(accessToken);
|
|
@@ -46,24 +45,23 @@ describe('Api()', function() {
|
|
|
46
45
|
expect(api.transportOptions.protocol).to.eql('https:');
|
|
47
46
|
done();
|
|
48
47
|
});
|
|
49
|
-
it('should parse the endpoint and use that if given', function(done) {
|
|
48
|
+
it('should parse the endpoint and use that if given', function (done) {
|
|
50
49
|
var transport = new (TestTransportGenerator())();
|
|
51
50
|
var endpoint = 'http://woo.foo.com/api/42';
|
|
52
51
|
var url = {
|
|
53
|
-
parse: function(e) {
|
|
52
|
+
parse: function (e) {
|
|
54
53
|
expect(e).to.eql(endpoint);
|
|
55
54
|
return {
|
|
56
55
|
hostname: 'woo.foo.com',
|
|
57
56
|
protocol: 'http:',
|
|
58
57
|
pathname: '/api/42',
|
|
59
|
-
path: '/api/42'
|
|
58
|
+
path: '/api/42',
|
|
60
59
|
};
|
|
61
|
-
}
|
|
60
|
+
},
|
|
62
61
|
};
|
|
63
|
-
var backup = null;
|
|
64
62
|
var accessToken = 'abc123';
|
|
65
|
-
var options = {accessToken: accessToken, endpoint: endpoint};
|
|
66
|
-
var api = new API(options, transport, url
|
|
63
|
+
var options = { accessToken: accessToken, endpoint: endpoint };
|
|
64
|
+
var api = new API(options, transport, url);
|
|
67
65
|
expect(api.accessToken).to.eql(accessToken);
|
|
68
66
|
expect(api.transportOptions.hostname).to.eql('woo.foo.com');
|
|
69
67
|
expect(api.transportOptions.path).to.match(/\/api\/42/);
|
|
@@ -72,57 +70,106 @@ describe('Api()', function() {
|
|
|
72
70
|
});
|
|
73
71
|
});
|
|
74
72
|
|
|
75
|
-
describe('postItem', function() {
|
|
76
|
-
it('should call post on the transport object', function(done) {
|
|
77
|
-
var response = 'yes'
|
|
73
|
+
describe('postItem', function () {
|
|
74
|
+
it('should call post on the transport object', function (done) {
|
|
75
|
+
var response = 'yes';
|
|
78
76
|
var transport = new (TestTransportGenerator())(null, response);
|
|
79
77
|
var url = {
|
|
80
|
-
parse: function(e) {
|
|
78
|
+
parse: function (e) {
|
|
81
79
|
expect(false).to.be.ok();
|
|
82
|
-
}
|
|
80
|
+
},
|
|
83
81
|
};
|
|
84
|
-
var backup = null;
|
|
85
82
|
var accessToken = 'abc123';
|
|
86
|
-
var options = {accessToken: accessToken};
|
|
87
|
-
var api = new API(options, transport, url
|
|
83
|
+
var options = { accessToken: accessToken };
|
|
84
|
+
var api = new API(options, transport, url);
|
|
88
85
|
|
|
89
|
-
var data = {a: 1};
|
|
90
|
-
api.postItem(data, function(err, resp) {
|
|
86
|
+
var data = { a: 1 };
|
|
87
|
+
api.postItem(data, function (err, resp) {
|
|
91
88
|
expect(err).to.not.be.ok();
|
|
92
89
|
expect(resp).to.eql(response);
|
|
93
90
|
expect(transport.postArgs.length).to.eql(1);
|
|
94
91
|
expect(transport.postArgs[0][0]).to.eql(accessToken);
|
|
95
92
|
expect(transport.postArgs[0][1].path).to.match(/\/item\//);
|
|
96
|
-
expect(transport.postArgs[0][2].access_token).to.eql(accessToken);
|
|
97
93
|
expect(transport.postArgs[0][2].data.a).to.eql(1);
|
|
98
94
|
done();
|
|
99
95
|
});
|
|
100
96
|
});
|
|
101
|
-
it('should stringify context', function(done) {
|
|
102
|
-
var response = 'yes'
|
|
97
|
+
it('should stringify context', function (done) {
|
|
98
|
+
var response = 'yes';
|
|
103
99
|
var transport = new (TestTransportGenerator())(null, response);
|
|
104
100
|
var url = {
|
|
105
|
-
parse: function(e) {
|
|
101
|
+
parse: function (e) {
|
|
106
102
|
expect(false).to.be.ok();
|
|
107
|
-
}
|
|
103
|
+
},
|
|
108
104
|
};
|
|
109
|
-
var backup = null;
|
|
110
105
|
var accessToken = 'abc123';
|
|
111
|
-
var options = {accessToken: accessToken};
|
|
112
|
-
var api = new API(options, transport, url
|
|
106
|
+
var options = { accessToken: accessToken };
|
|
107
|
+
var api = new API(options, transport, url);
|
|
113
108
|
|
|
114
|
-
var data = {a: 1, context: {some: [1, 2, 'stuff']}};
|
|
115
|
-
api.postItem(data, function(err, resp) {
|
|
109
|
+
var data = { a: 1, context: { some: [1, 2, 'stuff'] } };
|
|
110
|
+
api.postItem(data, function (err, resp) {
|
|
116
111
|
expect(err).to.not.be.ok();
|
|
117
112
|
expect(resp).to.eql(response);
|
|
118
113
|
expect(transport.postArgs.length).to.eql(1);
|
|
119
114
|
expect(transport.postArgs[0][0]).to.eql(accessToken);
|
|
120
115
|
expect(transport.postArgs[0][1].path).to.match(/\/item\//);
|
|
121
116
|
expect(transport.postArgs[0][1].method).to.eql('POST');
|
|
122
|
-
expect(transport.postArgs[0][2].access_token).to.eql(accessToken);
|
|
123
117
|
expect(transport.postArgs[0][2].data.a).to.eql(1);
|
|
124
|
-
expect(transport.postArgs[0][2].data.context).to.eql(
|
|
118
|
+
expect(transport.postArgs[0][2].data.context).to.eql(
|
|
119
|
+
'{"some":[1,2,"stuff"]}',
|
|
120
|
+
);
|
|
125
121
|
done();
|
|
126
122
|
});
|
|
127
123
|
});
|
|
128
124
|
});
|
|
125
|
+
|
|
126
|
+
describe('postSpans', function () {
|
|
127
|
+
let transport;
|
|
128
|
+
|
|
129
|
+
beforeEach(function () {
|
|
130
|
+
// Create mock transport
|
|
131
|
+
transport = {
|
|
132
|
+
post: sinon
|
|
133
|
+
.stub()
|
|
134
|
+
.callsFake((accessToken, options, payload, callback) => {
|
|
135
|
+
callback(null, { result: 'ok' });
|
|
136
|
+
}),
|
|
137
|
+
postJsonPayload: sinon.stub(),
|
|
138
|
+
};
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
afterEach(function () {
|
|
142
|
+
sinon.restore();
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
it('should call post on the transport object', async function () {
|
|
146
|
+
const urllib = await import('../src/browser/url.js');
|
|
147
|
+
const response = 'yes';
|
|
148
|
+
const url = {
|
|
149
|
+
parse: function (e) {
|
|
150
|
+
expect(false).to.be.ok();
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
const accessToken = 'abc123';
|
|
154
|
+
const options = {
|
|
155
|
+
accessToken: accessToken,
|
|
156
|
+
tracing: {
|
|
157
|
+
enabled: true,
|
|
158
|
+
endpoint: 'https://api.rollbar.com/api/1/session/',
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
const api = new API(options, transport, urllib);
|
|
162
|
+
|
|
163
|
+
const data = { a: 1 };
|
|
164
|
+
await api.postSpans(data)
|
|
165
|
+
|
|
166
|
+
expect(transport.post.called).to.be.true;
|
|
167
|
+
|
|
168
|
+
expect(transport.post.callCount).to.eql(1);
|
|
169
|
+
expect(transport.post.firstCall.args.length).to.eql(4);
|
|
170
|
+
expect(transport.post.firstCall.args[0]).to.eql(accessToken);
|
|
171
|
+
expect(transport.post.firstCall.args[1].path).to.match(/\/session\//);
|
|
172
|
+
expect(transport.post.firstCall.args[1].method).to.eql('POST');
|
|
173
|
+
expect(transport.post.firstCall.args[2].a).to.eql(1);
|
|
174
|
+
});
|
|
175
|
+
});
|