rollbar 2.17.0 → 2.19.2

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.
Files changed (55) hide show
  1. package/README.md +1 -1
  2. package/defaults.js +0 -1
  3. package/dist/rollbar.js +3810 -3556
  4. package/dist/rollbar.js.map +1 -1
  5. package/dist/rollbar.min.js +1 -1
  6. package/dist/rollbar.min.js.map +1 -1
  7. package/dist/rollbar.named-amd.js +3807 -3553
  8. package/dist/rollbar.named-amd.js.map +1 -1
  9. package/dist/rollbar.named-amd.min.js +1 -1
  10. package/dist/rollbar.named-amd.min.js.map +1 -1
  11. package/dist/rollbar.noconflict.umd.js +3807 -3553
  12. package/dist/rollbar.noconflict.umd.js.map +1 -1
  13. package/dist/rollbar.noconflict.umd.min.js +1 -1
  14. package/dist/rollbar.noconflict.umd.min.js.map +1 -1
  15. package/dist/rollbar.snippet.js +1 -1
  16. package/dist/rollbar.umd.js +3807 -3553
  17. package/dist/rollbar.umd.js.map +1 -1
  18. package/dist/rollbar.umd.min.js +1 -1
  19. package/dist/rollbar.umd.min.js.map +1 -1
  20. package/index.d.ts +2 -0
  21. package/package.json +1 -62
  22. package/src/api.js +13 -7
  23. package/src/browser/core.js +561 -0
  24. package/src/browser/defaults/scrubFields.js +59 -0
  25. package/src/browser/globalSetup.js +1 -41
  26. package/src/browser/rollbar.js +16 -544
  27. package/src/browser/shim.js +2 -1
  28. package/src/browser/telemetry.js +33 -17
  29. package/src/browser/transforms.js +28 -5
  30. package/src/browser/transport.js +13 -10
  31. package/src/browser/wrapGlobals.js +41 -0
  32. package/src/defaults.js +9 -0
  33. package/src/predicates.js +1 -0
  34. package/src/react-native/rollbar.js +9 -3
  35. package/src/react-native/transforms.js +7 -1
  36. package/src/react-native/transport.js +16 -10
  37. package/src/rollbar.js +9 -10
  38. package/src/scrub.js +93 -0
  39. package/src/server/rollbar.js +6 -2
  40. package/src/server/sourceMap/stackTrace.js +1 -2
  41. package/src/server/transforms.js +18 -4
  42. package/src/transforms.js +0 -1
  43. package/src/truncation.js +3 -2
  44. package/src/utility/traverse.js +38 -0
  45. package/src/utility.js +25 -107
  46. package/test/api.test.js +2 -0
  47. package/test/apiUtility.test.js +2 -1
  48. package/test/browser.core.test.js +555 -0
  49. package/test/browser.rollbar.test.js +116 -13
  50. package/test/browser.transforms.test.js +22 -2
  51. package/test/browser.transport.test.js +5 -2
  52. package/test/react-native.transport.test.js +5 -1
  53. package/test/server.transforms.test.js +70 -0
  54. package/test/truncation.test.js +2 -0
  55. package/test/utility.test.js +44 -13
@@ -0,0 +1,555 @@
1
+ /* globals expect */
2
+ /* globals describe */
3
+ /* globals it */
4
+ /* globals sinon */
5
+
6
+ // Use minimal browser package, with no optional components added.
7
+ var Rollbar = require('../src/browser/core');
8
+
9
+ describe('options.captureUncaught', function() {
10
+ beforeEach(function (done) {
11
+ // Load the HTML page, so errors can be generated.
12
+ document.write(window.__html__['examples/error.html']);
13
+
14
+ window.server = sinon.createFakeServer();
15
+ done();
16
+ });
17
+
18
+ afterEach(function () {
19
+ window.rollbar.configure({ autoInstrument: false });
20
+ window.server.restore();
21
+ });
22
+
23
+ function stubResponse(server) {
24
+ server.respondWith('POST', 'api/1/item',
25
+ [
26
+ 200,
27
+ { 'Content-Type': 'application/json' },
28
+ '{"err": 0, "result":{ "uuid": "d4c7acef55bf4c9ea95e4fe9428a8287"}}'
29
+ ]
30
+ );
31
+ }
32
+
33
+ it('should capture when enabled in constructor', function(done) {
34
+ var server = window.server;
35
+ stubResponse(server);
36
+ server.requests.length = 0;
37
+
38
+ var options = {
39
+ accessToken: 'POST_CLIENT_ITEM_TOKEN',
40
+ captureUncaught: true
41
+ };
42
+ var rollbar = window.rollbar = new Rollbar(options);
43
+
44
+ var element = document.getElementById('throw-error');
45
+ element.click();
46
+ server.respond();
47
+
48
+ var body = JSON.parse(server.requests[0].requestBody);
49
+
50
+ expect(body.access_token).to.eql('POST_CLIENT_ITEM_TOKEN');
51
+ expect(body.data.body.trace.exception.message).to.eql('test error');
52
+ expect(body.data.notifier.diagnostic.raw_error.message).to.eql('test error');
53
+ expect(body.data.notifier.diagnostic.is_uncaught).to.eql(true);
54
+
55
+ // karma doesn't unload the browser between tests, so the onerror handler
56
+ // will remain installed. Unset captureUncaught so the onerror handler
57
+ // won't affect other tests.
58
+ rollbar.configure({
59
+ captureUncaught: false
60
+ });
61
+
62
+ done();
63
+ });
64
+
65
+ it('should respond to enable/disable in configure', function(done) {
66
+ var server = window.server;
67
+ var element = document.getElementById('throw-error');
68
+ stubResponse(server);
69
+ server.requests.length = 0;
70
+
71
+ var options = {
72
+ accessToken: 'POST_CLIENT_ITEM_TOKEN',
73
+ captureUncaught: false
74
+ };
75
+ var rollbar = window.rollbar = new Rollbar(options);
76
+
77
+ element.click();
78
+ server.respond();
79
+ expect(server.requests.length).to.eql(0); // Disabled, no event
80
+ server.requests.length = 0;
81
+
82
+ rollbar.configure({
83
+ captureUncaught: true
84
+ });
85
+
86
+ element.click();
87
+ server.respond();
88
+
89
+ var body = JSON.parse(server.requests[0].requestBody);
90
+
91
+ expect(body.access_token).to.eql('POST_CLIENT_ITEM_TOKEN');
92
+ expect(body.data.body.trace.exception.message).to.eql('test error');
93
+ expect(body.data.notifier.diagnostic.is_anonymous).to.not.be.ok();
94
+
95
+ server.requests.length = 0;
96
+
97
+ rollbar.configure({
98
+ captureUncaught: false
99
+ });
100
+
101
+ element.click();
102
+ server.respond();
103
+ expect(server.requests.length).to.eql(0); // Disabled, no event
104
+
105
+ done();
106
+ });
107
+
108
+ // Test case expects Chrome, which is the currently configured karma js/browser
109
+ // engine at the time of this comment. However, karma's Chrome and ChromeHeadless
110
+ // don't actually behave like real Chrome so we settle for stubbing some things.
111
+ it('should capture external error data when inspectAnonymousErrors is true', function(done) {
112
+ var server = window.server;
113
+ stubResponse(server);
114
+ server.requests.length = 0;
115
+
116
+ // We're supposedly running on ChromeHeadless, but still need to spoof Chrome. :\
117
+ window.chrome = { runtime: true};
118
+
119
+ var options = {
120
+ accessToken: 'POST_CLIENT_ITEM_TOKEN',
121
+ captureUncaught: true,
122
+ inspectAnonymousErrors: true
123
+ };
124
+ var rollbar = window.rollbar = new Rollbar(options);
125
+
126
+ // Simulate receiving onerror without an error object.
127
+ rollbar.anonymousErrorsPending += 1;
128
+
129
+ try {
130
+ throw new Error('anon error')
131
+ } catch(e) {
132
+ Error.prepareStackTrace(e);
133
+ }
134
+
135
+ server.respond();
136
+
137
+ var body = JSON.parse(server.requests[0].requestBody);
138
+
139
+ expect(body.access_token).to.eql('POST_CLIENT_ITEM_TOKEN');
140
+ expect(body.data.body.trace.exception.message).to.eql('anon error');
141
+ expect(body.data.notifier.diagnostic.is_anonymous).to.eql(true);
142
+
143
+ // karma doesn't unload the browser between tests, so the onerror handler
144
+ // will remain installed. Unset captureUncaught so the onerror handler
145
+ // won't affect other tests.
146
+ rollbar.configure({
147
+ captureUncaught: false
148
+ });
149
+
150
+ done();
151
+ });
152
+
153
+ it('should ignore duplicate errors by default', function(done) {
154
+ var server = window.server;
155
+ stubResponse(server);
156
+ server.requests.length = 0;
157
+
158
+ var options = {
159
+ accessToken: 'POST_CLIENT_ITEM_TOKEN',
160
+ captureUncaught: true
161
+ };
162
+ var rollbar = window.rollbar = new Rollbar(options);
163
+
164
+ var element = document.getElementById('throw-error');
165
+
166
+ // generate same error twice
167
+ for(var i = 0; i < 2; i++) {
168
+ element.click(); // use for loop to ensure the stack traces have identical line/col info
169
+ }
170
+ server.respond();
171
+
172
+ // transmit only once
173
+ expect(server.requests.length).to.eql(1);
174
+
175
+ var body = JSON.parse(server.requests[0].requestBody);
176
+
177
+ expect(body.access_token).to.eql('POST_CLIENT_ITEM_TOKEN');
178
+ expect(body.data.body.trace.exception.message).to.eql('test error');
179
+
180
+ // karma doesn't unload the browser between tests, so the onerror handler
181
+ // will remain installed. Unset captureUncaught so the onerror handler
182
+ // won't affect other tests.
183
+ rollbar.configure({
184
+ captureUncaught: false
185
+ });
186
+
187
+ done();
188
+ });
189
+
190
+ it('should transmit duplicate errors when set in config', function(done) {
191
+ var server = window.server;
192
+ stubResponse(server);
193
+ server.requests.length = 0;
194
+
195
+ var options = {
196
+ accessToken: 'POST_CLIENT_ITEM_TOKEN',
197
+ captureUncaught: true,
198
+ ignoreDuplicateErrors: false
199
+ };
200
+ var rollbar = window.rollbar = new Rollbar(options);
201
+
202
+ var element = document.getElementById('throw-error');
203
+
204
+ // generate same error twice
205
+ for(var i = 0; i < 2; i++) {
206
+ element.click(); // use for loop to ensure the stack traces have identical line/col info
207
+ }
208
+ server.respond();
209
+
210
+ // transmit both errors
211
+ expect(server.requests.length).to.eql(2);
212
+
213
+ var body = JSON.parse(server.requests[0].requestBody);
214
+
215
+ expect(body.access_token).to.eql('POST_CLIENT_ITEM_TOKEN');
216
+ expect(body.data.body.trace.exception.message).to.eql('test error');
217
+
218
+ // karma doesn't unload the browser between tests, so the onerror handler
219
+ // will remain installed. Unset captureUncaught so the onerror handler
220
+ // won't affect other tests.
221
+ rollbar.configure({
222
+ captureUncaught: false
223
+ });
224
+
225
+ done();
226
+ });
227
+ it('should send DOMException as trace_chain', function(done) {
228
+ var server = window.server;
229
+ stubResponse(server);
230
+ server.requests.length = 0;
231
+
232
+ var options = {
233
+ accessToken: 'POST_CLIENT_ITEM_TOKEN',
234
+ captureUncaught: true
235
+ };
236
+ var rollbar = window.rollbar = new Rollbar(options);
237
+
238
+ var element = document.getElementById('throw-dom-exception');
239
+ element.click();
240
+ server.respond();
241
+
242
+ var body = JSON.parse(server.requests[0].requestBody);
243
+
244
+ expect(body.access_token).to.eql('POST_CLIENT_ITEM_TOKEN');
245
+ expect(body.data.body.trace_chain[0].exception.message).to.eql('test DOMException');
246
+
247
+ // karma doesn't unload the browser between tests, so the onerror handler
248
+ // will remain installed. Unset captureUncaught so the onerror handler
249
+ // won't affect other tests.
250
+ rollbar.configure({
251
+ captureUncaught: false
252
+ });
253
+
254
+ done();
255
+ });
256
+
257
+ it('should capture exta frames when stackTraceLimit is set', function(done) {
258
+ var server = window.server;
259
+ stubResponse(server);
260
+ server.requests.length = 0;
261
+
262
+ var oldLimit = Error.stackTraceLimit;
263
+ var options = {
264
+ accessToken: 'POST_CLIENT_ITEM_TOKEN',
265
+ captureUncaught: true,
266
+ stackTraceLimit: 50
267
+ };
268
+ var rollbar = window.rollbar = new Rollbar(options);
269
+
270
+ var element = document.getElementById('throw-depp-stack-error');
271
+ element.click();
272
+ server.respond();
273
+
274
+ var body = JSON.parse(server.requests[0].requestBody);
275
+
276
+ expect(body.access_token).to.eql('POST_CLIENT_ITEM_TOKEN');
277
+ expect(body.data.body.trace.exception.message).to.eql('deep stack error');
278
+ expect(body.data.body.trace.frames.length).to.be.above(20);
279
+
280
+ // karma doesn't unload the browser between tests, so the onerror handler
281
+ // will remain installed. Unset captureUncaught so the onerror handler
282
+ // won't affect other tests.
283
+ rollbar.configure({
284
+ captureUncaught: false,
285
+ stackTraceLimit: oldLimit // reset to default
286
+ });
287
+
288
+ done();
289
+ });
290
+ });
291
+
292
+ describe('options.captureUnhandledRejections', function() {
293
+ beforeEach(function (done) {
294
+ window.server = sinon.createFakeServer();
295
+ done();
296
+ });
297
+
298
+ afterEach(function () {
299
+ window.rollbar.configure({ autoInstrument: false });
300
+ window.server.restore();
301
+ });
302
+
303
+ function stubResponse(server) {
304
+ server.respondWith('POST', 'api/1/item',
305
+ [
306
+ 200,
307
+ { 'Content-Type': 'application/json' },
308
+ '{"err": 0, "result":{ "uuid": "d4c7acef55bf4c9ea95e4fe9428a8287"}}'
309
+ ]
310
+ );
311
+ }
312
+
313
+ it('should capture when enabled in constructor', function(done) {
314
+ var server = window.server;
315
+ stubResponse(server);
316
+ server.requests.length = 0;
317
+
318
+ var options = {
319
+ accessToken: 'POST_CLIENT_ITEM_TOKEN',
320
+ captureUnhandledRejections: true
321
+ };
322
+ var rollbar = window.rollbar = new Rollbar(options);
323
+
324
+ Promise.reject(new Error('test reject'));
325
+
326
+ setTimeout(function() {
327
+ server.respond();
328
+
329
+ var body = JSON.parse(server.requests[0].requestBody);
330
+
331
+ expect(body.access_token).to.eql('POST_CLIENT_ITEM_TOKEN');
332
+ expect(body.data.body.trace.exception.message).to.eql('test reject');
333
+ expect(body.data.notifier.diagnostic.is_uncaught).to.eql(true);
334
+
335
+ rollbar.configure({
336
+ captureUnhandledRejections: false
337
+ });
338
+ window.removeEventListener('unhandledrejection', window._rollbarURH);
339
+
340
+ done();
341
+ }, 500);
342
+ });
343
+
344
+ it('should respond to enable in configure', function(done) {
345
+ var server = window.server;
346
+ stubResponse(server);
347
+ server.requests.length = 0;
348
+
349
+ var options = {
350
+ accessToken: 'POST_CLIENT_ITEM_TOKEN',
351
+ captureUnhandledRejections: false
352
+ };
353
+ var rollbar = window.rollbar = new Rollbar(options);
354
+
355
+ rollbar.configure({
356
+ captureUnhandledRejections: true
357
+ });
358
+
359
+ Promise.reject(new Error('test reject'));
360
+
361
+ setTimeout(function() {
362
+ server.respond();
363
+
364
+ var body = JSON.parse(server.requests[0].requestBody);
365
+
366
+ expect(body.access_token).to.eql('POST_CLIENT_ITEM_TOKEN');
367
+ expect(body.data.body.trace.exception.message).to.eql('test reject');
368
+
369
+ server.requests.length = 0;
370
+
371
+ rollbar.configure({
372
+ captureUnhandledRejections: false
373
+ });
374
+ window.removeEventListener('unhandledrejection', window._rollbarURH);
375
+
376
+ done();
377
+ }, 500);
378
+ });
379
+
380
+ it('should respond to disable in configure', function(done) {
381
+ var server = window.server;
382
+ stubResponse(server);
383
+ server.requests.length = 0;
384
+
385
+ var options = {
386
+ accessToken: 'POST_CLIENT_ITEM_TOKEN',
387
+ captureUnhandledRejections: true
388
+ };
389
+ var rollbar = window.rollbar = new Rollbar(options);
390
+
391
+ rollbar.configure({
392
+ captureUnhandledRejections: false
393
+ });
394
+
395
+ Promise.reject(new Error('test reject'));
396
+
397
+ setTimeout(function() {
398
+ server.respond();
399
+
400
+ expect(server.requests.length).to.eql(0); // Disabled, no event
401
+ server.requests.length = 0;
402
+
403
+ window.removeEventListener('unhandledrejection', window._rollbarURH);
404
+
405
+ done();
406
+ }, 500);
407
+ })
408
+ });
409
+
410
+ describe('log', function() {
411
+ beforeEach(function (done) {
412
+ window.server = sinon.createFakeServer();
413
+ done();
414
+ });
415
+
416
+ afterEach(function () {
417
+ window.rollbar.configure({ autoInstrument: false });
418
+ window.server.restore();
419
+ });
420
+
421
+ function stubResponse(server) {
422
+ server.respondWith('POST', 'api/1/item',
423
+ [
424
+ 200,
425
+ { 'Content-Type': 'application/json' },
426
+ '{"err": 0, "result":{ "uuid": "d4c7acef55bf4c9ea95e4fe9428a8287"}}'
427
+ ]
428
+ );
429
+ }
430
+
431
+ it('should send message when called with message and extra args', function(done) {
432
+ var server = window.server;
433
+ stubResponse(server);
434
+ server.requests.length = 0;
435
+
436
+ var options = {
437
+ accessToken: 'POST_CLIENT_ITEM_TOKEN'
438
+ };
439
+ var rollbar = window.rollbar = new Rollbar(options);
440
+
441
+ rollbar.log('test message', { 'foo': 'bar' });
442
+
443
+ server.respond();
444
+
445
+ var body = JSON.parse(server.requests[0].requestBody);
446
+
447
+ expect(body.data.body.message.body).to.eql('test message');
448
+ expect(body.data.body.message.extra).to.eql({ 'foo': 'bar' });
449
+ expect(body.data.notifier.diagnostic.is_uncaught).to.eql(undefined);
450
+ expect(body.data.notifier.diagnostic.original_arg_types).to.eql(['string', 'object']);
451
+
452
+ done();
453
+ })
454
+
455
+ it('should send exception when called with error and extra args', function(done) {
456
+ var server = window.server;
457
+ stubResponse(server);
458
+ server.requests.length = 0;
459
+
460
+ var options = {
461
+ accessToken: 'POST_CLIENT_ITEM_TOKEN'
462
+ };
463
+ var rollbar = window.rollbar = new Rollbar(options);
464
+
465
+ rollbar.log(new Error('test error'), { 'foo': 'bar' });
466
+
467
+ server.respond();
468
+
469
+ var body = JSON.parse(server.requests[0].requestBody);
470
+
471
+ expect(body.data.body.trace.exception.message).to.eql('test error');
472
+ expect(body.data.body.trace.extra).to.eql({ 'foo': 'bar' });
473
+ expect(body.data.notifier.diagnostic.is_uncaught).to.eql(undefined);
474
+ expect(body.data.notifier.diagnostic.original_arg_types).to.eql(['error', 'object']);
475
+
476
+ done();
477
+ })
478
+
479
+ it('should add custom data when called with error context', function(done) {
480
+ var server = window.server;
481
+ stubResponse(server);
482
+ server.requests.length = 0;
483
+
484
+ var options = {
485
+ accessToken: 'POST_CLIENT_ITEM_TOKEN',
486
+ addErrorContext: true
487
+ };
488
+ var rollbar = window.rollbar = new Rollbar(options);
489
+
490
+ var err = new Error('test error');
491
+ err.rollbarContext = { err: 'test' };
492
+
493
+ rollbar.error(err, { 'foo': 'bar' });
494
+
495
+ server.respond();
496
+
497
+ var body = JSON.parse(server.requests[0].requestBody);
498
+
499
+ expect(body.data.body.trace.exception.message).to.eql('test error');
500
+ expect(body.data.custom.foo).to.eql('bar');
501
+ expect(body.data.custom.err).to.eql('test');
502
+
503
+ done();
504
+ })
505
+
506
+ it('should send message when called with only null arguments', function(done) {
507
+ var server = window.server;
508
+ stubResponse(server);
509
+ server.requests.length = 0;
510
+
511
+ var options = {
512
+ accessToken: 'POST_CLIENT_ITEM_TOKEN',
513
+ captureUnhandledRejections: true
514
+ };
515
+ var rollbar = window.rollbar = new Rollbar(options);
516
+
517
+ rollbar.log(null);
518
+
519
+ server.respond();
520
+
521
+ var body = JSON.parse(server.requests[0].requestBody);
522
+
523
+ expect(body.data.body.message.body).to.eql('Item sent with null or missing arguments.');
524
+ expect(body.data.notifier.diagnostic.original_arg_types).to.eql(['null']);
525
+
526
+ done();
527
+ })
528
+
529
+ it('should skipFrames when set', function(done) {
530
+ var server = window.server;
531
+ stubResponse(server);
532
+ server.requests.length = 0;
533
+
534
+ var options = {
535
+ accessToken: 'POST_CLIENT_ITEM_TOKEN',
536
+ captureUnhandledRejections: true
537
+ };
538
+ var rollbar = window.rollbar = new Rollbar(options);
539
+
540
+ var error = new Error('error with stack');
541
+
542
+ rollbar.log(error);
543
+ rollbar.log(error, { skipFrames: 1 });
544
+
545
+ server.respond();
546
+
547
+ var frames1 = JSON.parse(server.requests[0].requestBody).data.body.trace.frames;
548
+ var frames2 = JSON.parse(server.requests[1].requestBody).data.body.trace.frames;
549
+
550
+ expect(frames1.length).to.eql(frames2.length + 1);
551
+ expect(frames1.slice(0,-1)).to.eql(frames2);
552
+
553
+ done();
554
+ })
555
+ });