@honeybadger-io/js 3.2.8 → 4.0.0-beta.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.
- package/dist/browser/honeybadger.js +267 -119
- package/dist/browser/honeybadger.js.map +1 -1
- package/dist/browser/honeybadger.min.js +1 -1
- package/dist/browser/honeybadger.min.js.map +1 -1
- package/dist/browser/types/browser/util.d.ts +1 -1
- package/dist/browser/types/core/client.d.ts +23 -3
- package/dist/browser/types/core/store.d.ts +7 -0
- package/dist/browser/types/core/types.d.ts +8 -4
- package/dist/browser/types/core/util.d.ts +5 -3
- package/dist/browser/types/server/async_store.d.ts +5 -0
- package/dist/browser/types/server.d.ts +1 -0
- package/dist/server/honeybadger.d.ts +3 -1
- package/dist/server/honeybadger.js +375 -142
- package/dist/server/types/core/client.d.ts +23 -3
- package/dist/server/types/core/store.d.ts +7 -0
- package/dist/server/types/core/types.d.ts +8 -4
- package/dist/server/types/core/util.d.ts +5 -3
- package/dist/server/types/server/async_store.d.ts +5 -0
- package/dist/server/types/server/middleware.d.ts +3 -5
- package/dist/server/types/server/util.d.ts +7 -0
- package/dist/server/types/server.d.ts +3 -1
- package/honeybadger.d.ts +2 -1
- package/package.json +25 -22
- package/dist/browser/types/core/error.d.ts +0 -3
- package/dist/server/types/core/error.d.ts +0 -3
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
|
3
3
|
typeof define === 'function' && define.amd ? define(factory) :
|
|
4
4
|
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Honeybadger = factory());
|
|
5
|
-
}(this, (function () { 'use strict';
|
|
5
|
+
})(this, (function () { 'use strict';
|
|
6
6
|
|
|
7
7
|
/*! *****************************************************************************
|
|
8
8
|
Copyright (c) Microsoft Corporation.
|
|
@@ -215,7 +215,8 @@
|
|
|
215
215
|
function makeBacktrace(stack, shift) {
|
|
216
216
|
if (shift === void 0) { shift = 0; }
|
|
217
217
|
try {
|
|
218
|
-
var backtrace = parse(stack)
|
|
218
|
+
var backtrace = parse(stack)
|
|
219
|
+
.map(function (line) {
|
|
219
220
|
return {
|
|
220
221
|
file: line.file,
|
|
221
222
|
method: line.methodName,
|
|
@@ -231,24 +232,46 @@
|
|
|
231
232
|
return [];
|
|
232
233
|
}
|
|
233
234
|
}
|
|
235
|
+
function getSourceForBacktrace(backtrace, getSourceFileHandler, cb) {
|
|
236
|
+
if (!getSourceFileHandler || !backtrace || !backtrace.length) {
|
|
237
|
+
cb([]);
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
var result = [];
|
|
241
|
+
var getSourceFromFile = function (index) {
|
|
242
|
+
if (index === void 0) { index = 0; }
|
|
243
|
+
if (!backtrace.length) {
|
|
244
|
+
return cb(result);
|
|
245
|
+
}
|
|
246
|
+
var trace = backtrace.splice(0)[index];
|
|
247
|
+
getSourceFileHandler(trace.file, (function (fileContent) {
|
|
248
|
+
result[index] = getSourceCodeSnippet(fileContent, trace.number);
|
|
249
|
+
getSourceFromFile(index + 1);
|
|
250
|
+
}));
|
|
251
|
+
};
|
|
252
|
+
getSourceFromFile();
|
|
253
|
+
}
|
|
234
254
|
function runBeforeNotifyHandlers(notice, handlers) {
|
|
255
|
+
var result = true;
|
|
235
256
|
for (var i = 0, len = handlers.length; i < len; i++) {
|
|
236
257
|
var handler = handlers[i];
|
|
237
258
|
if (handler(notice) === false) {
|
|
238
|
-
|
|
259
|
+
result = false;
|
|
239
260
|
}
|
|
240
261
|
}
|
|
241
|
-
return
|
|
262
|
+
return result;
|
|
242
263
|
}
|
|
243
264
|
function runAfterNotifyHandlers(notice, handlers, error) {
|
|
244
|
-
if (
|
|
265
|
+
if (notice && notice.afterNotify) {
|
|
266
|
+
notice.afterNotify(error, notice);
|
|
267
|
+
}
|
|
245
268
|
for (var i = 0, len = handlers.length; i < len; i++) {
|
|
246
269
|
handlers[i](error, notice);
|
|
247
270
|
}
|
|
248
271
|
return true;
|
|
249
272
|
}
|
|
250
273
|
// Returns a new object with properties from other object.
|
|
251
|
-
function
|
|
274
|
+
function shallowClone(obj) {
|
|
252
275
|
if (typeof (obj) !== 'object' || obj === null) {
|
|
253
276
|
return {};
|
|
254
277
|
}
|
|
@@ -275,8 +298,14 @@
|
|
|
275
298
|
return false;
|
|
276
299
|
}
|
|
277
300
|
function canSerialize(obj) {
|
|
278
|
-
|
|
279
|
-
|
|
301
|
+
var typeOfObj = typeof obj;
|
|
302
|
+
// Functions are TMI
|
|
303
|
+
if (/function/.test(typeOfObj)) {
|
|
304
|
+
// Let special toJSON method pass as it's used by JSON.stringify (#722)
|
|
305
|
+
return obj.name === 'toJSON';
|
|
306
|
+
}
|
|
307
|
+
// Symbols can't convert to strings.
|
|
308
|
+
if (/symbol/.test(typeOfObj)) {
|
|
280
309
|
return false;
|
|
281
310
|
}
|
|
282
311
|
if (obj === null) {
|
|
@@ -325,7 +354,7 @@
|
|
|
325
354
|
return serialize(obj, depth);
|
|
326
355
|
}
|
|
327
356
|
catch (e) {
|
|
328
|
-
return "[ERROR] "
|
|
357
|
+
return "[ERROR] ".concat(e);
|
|
329
358
|
}
|
|
330
359
|
}
|
|
331
360
|
return safeSerialize(obj);
|
|
@@ -338,8 +367,13 @@
|
|
|
338
367
|
for (var _i = 0; _i < arguments.length; _i++) {
|
|
339
368
|
args[_i] = arguments[_i];
|
|
340
369
|
}
|
|
341
|
-
if (method === 'debug'
|
|
342
|
-
|
|
370
|
+
if (method === 'debug') {
|
|
371
|
+
if (!client.config.debug) {
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
// Log at default level so that you don't need to also enable verbose
|
|
375
|
+
// logging in Chrome.
|
|
376
|
+
method = 'log';
|
|
343
377
|
}
|
|
344
378
|
args.unshift('[Honeybadger]');
|
|
345
379
|
(_a = client.config.logger)[method].apply(_a, args);
|
|
@@ -362,12 +396,12 @@
|
|
|
362
396
|
if (!thing) {
|
|
363
397
|
notice = {};
|
|
364
398
|
}
|
|
365
|
-
else if (Object.prototype.toString.call(thing) === '[object Error]') {
|
|
399
|
+
else if (thing instanceof Error || Object.prototype.toString.call(thing) === '[object Error]') {
|
|
366
400
|
var e = thing;
|
|
367
401
|
notice = merge(thing, { name: e.name, message: e.message, stack: e.stack });
|
|
368
402
|
}
|
|
369
403
|
else if (typeof thing === 'object') {
|
|
370
|
-
notice =
|
|
404
|
+
notice = shallowClone(thing);
|
|
371
405
|
}
|
|
372
406
|
else {
|
|
373
407
|
var m = String(thing);
|
|
@@ -403,7 +437,7 @@
|
|
|
403
437
|
function endpoint(config, path) {
|
|
404
438
|
var endpoint = config.endpoint.trim().replace(/\/$/, '');
|
|
405
439
|
path = path.trim().replace(/(^\/|\/$)/g, '');
|
|
406
|
-
return endpoint
|
|
440
|
+
return "".concat(endpoint, "/").concat(path);
|
|
407
441
|
}
|
|
408
442
|
function generateStackTrace() {
|
|
409
443
|
try {
|
|
@@ -462,7 +496,9 @@
|
|
|
462
496
|
return newObj;
|
|
463
497
|
}
|
|
464
498
|
if (is('Array', obj)) {
|
|
465
|
-
return obj.map(function (v) {
|
|
499
|
+
return obj.map(function (v) {
|
|
500
|
+
return filter(v);
|
|
501
|
+
});
|
|
466
502
|
}
|
|
467
503
|
if (is('Function', obj)) {
|
|
468
504
|
return '[FUNC]';
|
|
@@ -498,7 +534,7 @@
|
|
|
498
534
|
query.split(/[&]\s?/).forEach(function (pair) {
|
|
499
535
|
var _a = pair.split('=', 2), key = _a[0], value = _a[1];
|
|
500
536
|
if (filterMatch(key, filters)) {
|
|
501
|
-
result = result.replace(key
|
|
537
|
+
result = result.replace("".concat(key, "=").concat(value), "".concat(key, "=[FILTERED]"));
|
|
502
538
|
}
|
|
503
539
|
});
|
|
504
540
|
return result;
|
|
@@ -512,34 +548,64 @@
|
|
|
512
548
|
});
|
|
513
549
|
return formattedVars;
|
|
514
550
|
}
|
|
551
|
+
function getSourceCodeSnippet(fileData, lineNumber, sourceRadius) {
|
|
552
|
+
if (sourceRadius === void 0) { sourceRadius = 2; }
|
|
553
|
+
if (!fileData) {
|
|
554
|
+
return null;
|
|
555
|
+
}
|
|
556
|
+
var lines = fileData.split('\n');
|
|
557
|
+
// add one empty line because array index starts from 0, but error line number is counted from 1
|
|
558
|
+
lines.unshift('');
|
|
559
|
+
var start = lineNumber - sourceRadius;
|
|
560
|
+
var end = lineNumber + sourceRadius;
|
|
561
|
+
var result = {};
|
|
562
|
+
for (var i = start; i <= end; i++) {
|
|
563
|
+
var line = lines[i];
|
|
564
|
+
if (typeof line === 'string') {
|
|
565
|
+
result[i] = line;
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
return result;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
var GlobalStore = /** @class */ (function () {
|
|
572
|
+
function GlobalStore(store) {
|
|
573
|
+
this.store = store;
|
|
574
|
+
}
|
|
575
|
+
GlobalStore.prototype.getStore = function () {
|
|
576
|
+
return this.store;
|
|
577
|
+
};
|
|
578
|
+
GlobalStore.prototype.run = function (store, callback) {
|
|
579
|
+
var args = [];
|
|
580
|
+
for (var _i = 2; _i < arguments.length; _i++) {
|
|
581
|
+
args[_i - 2] = arguments[_i];
|
|
582
|
+
}
|
|
583
|
+
this.store = store;
|
|
584
|
+
return callback.apply(void 0, args);
|
|
585
|
+
};
|
|
586
|
+
return GlobalStore;
|
|
587
|
+
}());
|
|
515
588
|
|
|
516
589
|
var notifier = {
|
|
517
590
|
name: 'honeybadger-js',
|
|
518
591
|
url: 'https://github.com/honeybadger-io/honeybadger-js',
|
|
519
|
-
version: '
|
|
592
|
+
version: '4.0.0-beta.2'
|
|
520
593
|
};
|
|
521
|
-
// Split at commas
|
|
522
|
-
var TAG_SEPARATOR =
|
|
523
|
-
// Removes any non-word characters
|
|
524
|
-
var TAG_SANITIZER = /[^\w]/g;
|
|
525
|
-
// Checks for blank strings
|
|
526
|
-
var STRING_EMPTY = '';
|
|
594
|
+
// Split at commas and spaces
|
|
595
|
+
var TAG_SEPARATOR = /,|\s+/;
|
|
527
596
|
// Checks for non-blank characters
|
|
528
597
|
var NOT_BLANK = /\S/;
|
|
529
598
|
var Client = /** @class */ (function () {
|
|
530
599
|
function Client(opts) {
|
|
531
600
|
if (opts === void 0) { opts = {}; }
|
|
532
|
-
/** @internal */
|
|
533
601
|
this.__pluginsExecuted = false;
|
|
534
|
-
|
|
535
|
-
this.__context = {};
|
|
536
|
-
/** @internal */
|
|
537
|
-
this.__breadcrumbs = [];
|
|
538
|
-
/** @internal */
|
|
602
|
+
this.__store = null;
|
|
539
603
|
this.__beforeNotifyHandlers = [];
|
|
540
|
-
/** @internal */
|
|
541
604
|
this.__afterNotifyHandlers = [];
|
|
542
|
-
this.config = __assign({ apiKey: null, endpoint: 'https://api.honeybadger.io', environment: null, hostname: null, projectRoot: null, component: null, action: null, revision: null, reportData: null, breadcrumbsEnabled: true, maxBreadcrumbs: 40, maxObjectDepth: 8, logger: console, developmentEnvironments: ['dev', 'development', 'test'],
|
|
605
|
+
this.config = __assign({ apiKey: null, endpoint: 'https://api.honeybadger.io', environment: null, hostname: null, projectRoot: null, component: null, action: null, revision: null, reportData: null, breadcrumbsEnabled: true, maxBreadcrumbs: 40, maxObjectDepth: 8, logger: console, developmentEnvironments: ['dev', 'development', 'test'], debug: false, tags: null, enableUncaught: true, enableUnhandledRejection: true, afterUncaught: function () { return true; }, filters: ['creditcard', 'password'], __plugins: [] }, opts);
|
|
606
|
+
// First, we go with the global (shared) store.
|
|
607
|
+
// Webserver middleware can then switch to the AsyncStore for async context tracking.
|
|
608
|
+
this.__store = new GlobalStore({ context: {}, breadcrumbs: [] });
|
|
543
609
|
this.logger = logger(this);
|
|
544
610
|
}
|
|
545
611
|
Client.prototype.factory = function (_opts) {
|
|
@@ -560,6 +626,10 @@
|
|
|
560
626
|
}
|
|
561
627
|
return this;
|
|
562
628
|
};
|
|
629
|
+
/** @internal */
|
|
630
|
+
Client.prototype.__setStore = function (store) {
|
|
631
|
+
this.__store = store;
|
|
632
|
+
};
|
|
563
633
|
Client.prototype.beforeNotify = function (handler) {
|
|
564
634
|
this.__beforeNotifyHandlers.push(handler);
|
|
565
635
|
return this;
|
|
@@ -570,41 +640,129 @@
|
|
|
570
640
|
};
|
|
571
641
|
Client.prototype.setContext = function (context) {
|
|
572
642
|
if (typeof context === 'object') {
|
|
573
|
-
|
|
643
|
+
var store = this.__store.getStore();
|
|
644
|
+
store.context = merge(store.context, context);
|
|
574
645
|
}
|
|
575
646
|
return this;
|
|
576
647
|
};
|
|
577
648
|
Client.prototype.resetContext = function (context) {
|
|
578
649
|
this.logger.warn('Deprecation warning: `Honeybadger.resetContext()` has been deprecated; please use `Honeybadger.clear()` instead.');
|
|
650
|
+
var store = this.__store.getStore();
|
|
579
651
|
if (typeof context === 'object' && context !== null) {
|
|
580
|
-
|
|
652
|
+
store.context = context;
|
|
581
653
|
}
|
|
582
654
|
else {
|
|
583
|
-
|
|
655
|
+
store.context = {};
|
|
584
656
|
}
|
|
585
657
|
return this;
|
|
586
658
|
};
|
|
587
659
|
Client.prototype.clear = function () {
|
|
588
|
-
|
|
589
|
-
|
|
660
|
+
var store = this.__store.getStore();
|
|
661
|
+
store.context = {};
|
|
662
|
+
store.breadcrumbs = [];
|
|
590
663
|
return this;
|
|
591
664
|
};
|
|
592
|
-
Client.prototype.notify = function (
|
|
665
|
+
Client.prototype.notify = function (noticeable, name, extra) {
|
|
666
|
+
var _this = this;
|
|
593
667
|
if (name === void 0) { name = undefined; }
|
|
594
668
|
if (extra === void 0) { extra = undefined; }
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
669
|
+
var preConditionError = null;
|
|
670
|
+
var notice = this.makeNotice(noticeable, name, extra);
|
|
671
|
+
if (!notice) {
|
|
672
|
+
this.logger.debug('failed to build error report');
|
|
673
|
+
preConditionError = new Error('failed to build error report');
|
|
598
674
|
}
|
|
599
|
-
if (!this.
|
|
600
|
-
this.logger.debug('
|
|
601
|
-
|
|
675
|
+
if (!preConditionError && this.config.reportData === false) {
|
|
676
|
+
this.logger.debug('skipping error report: honeybadger.js is disabled', notice);
|
|
677
|
+
preConditionError = new Error('honeybadger.js is disabled');
|
|
602
678
|
}
|
|
603
|
-
if (!this.
|
|
604
|
-
this.logger.
|
|
679
|
+
if (!preConditionError && this.__developmentMode()) {
|
|
680
|
+
this.logger.log('honeybadger.js is in development mode; the following error report will be sent in production.', notice);
|
|
681
|
+
preConditionError = new Error('honeybadger.js is in development mode');
|
|
682
|
+
}
|
|
683
|
+
if (!preConditionError && !this.config.apiKey) {
|
|
684
|
+
this.logger.warn('could not send error report: no API key has been configured', notice);
|
|
685
|
+
preConditionError = new Error('missing API key');
|
|
686
|
+
}
|
|
687
|
+
var beforeNotifyResult = runBeforeNotifyHandlers(notice, this.__beforeNotifyHandlers);
|
|
688
|
+
if (!preConditionError && !beforeNotifyResult) {
|
|
689
|
+
this.logger.debug('skipping error report: beforeNotify handlers returned false', notice);
|
|
690
|
+
preConditionError = new Error('beforeNotify handlers returned false');
|
|
691
|
+
}
|
|
692
|
+
if (preConditionError) {
|
|
693
|
+
runAfterNotifyHandlers(notice, this.__afterNotifyHandlers, preConditionError);
|
|
605
694
|
return false;
|
|
606
695
|
}
|
|
607
|
-
|
|
696
|
+
this.addBreadcrumb('Honeybadger Notice', {
|
|
697
|
+
category: 'notice',
|
|
698
|
+
metadata: {
|
|
699
|
+
message: notice.message,
|
|
700
|
+
name: notice.name,
|
|
701
|
+
stack: notice.stack
|
|
702
|
+
}
|
|
703
|
+
});
|
|
704
|
+
var breadcrumbs = this.__getStoreOrDefaultObject().breadcrumbs;
|
|
705
|
+
notice.__breadcrumbs = this.config.breadcrumbsEnabled ? breadcrumbs.slice() : [];
|
|
706
|
+
// we need to have the source file data before the beforeNotifyHandlers,
|
|
707
|
+
// in case they modify them
|
|
708
|
+
var sourceCodeData = notice && notice.backtrace ? notice.backtrace.map(function (trace) { return shallowClone(trace); }) : null;
|
|
709
|
+
getSourceForBacktrace(sourceCodeData, this.__getSourceFileHandler, function (sourcePerTrace) {
|
|
710
|
+
sourcePerTrace.forEach(function (source, index) {
|
|
711
|
+
notice.backtrace[index].source = source;
|
|
712
|
+
});
|
|
713
|
+
_this.__send(notice);
|
|
714
|
+
});
|
|
715
|
+
return true;
|
|
716
|
+
};
|
|
717
|
+
/**
|
|
718
|
+
* An async version of {@link notify} that resolves only after the notice has been reported to Honeybadger.
|
|
719
|
+
* Implemented using the {@link afterNotify} hook.
|
|
720
|
+
* Rejects if for any reason the report failed to be reported.
|
|
721
|
+
* Useful in serverless environments (AWS Lambda).
|
|
722
|
+
*/
|
|
723
|
+
Client.prototype.notifyAsync = function (noticeable, name, extra) {
|
|
724
|
+
var _this = this;
|
|
725
|
+
if (name === void 0) { name = undefined; }
|
|
726
|
+
if (extra === void 0) { extra = undefined; }
|
|
727
|
+
return new Promise(function (resolve, reject) {
|
|
728
|
+
var applyAfterNotify = function (partialNotice) {
|
|
729
|
+
var originalAfterNotify = partialNotice.afterNotify;
|
|
730
|
+
partialNotice.afterNotify = function (err) {
|
|
731
|
+
originalAfterNotify === null || originalAfterNotify === void 0 ? void 0 : originalAfterNotify.call(_this, err);
|
|
732
|
+
if (err) {
|
|
733
|
+
return reject(err);
|
|
734
|
+
}
|
|
735
|
+
resolve();
|
|
736
|
+
};
|
|
737
|
+
};
|
|
738
|
+
// We have to respect any afterNotify hooks that come from the arguments
|
|
739
|
+
var objectToOverride;
|
|
740
|
+
if (noticeable.afterNotify) {
|
|
741
|
+
objectToOverride = noticeable;
|
|
742
|
+
}
|
|
743
|
+
else if (name && name.afterNotify) {
|
|
744
|
+
objectToOverride = name;
|
|
745
|
+
}
|
|
746
|
+
else if (extra && extra.afterNotify) {
|
|
747
|
+
objectToOverride = extra;
|
|
748
|
+
}
|
|
749
|
+
else if (name && typeof name === 'object') {
|
|
750
|
+
objectToOverride = name;
|
|
751
|
+
}
|
|
752
|
+
else if (extra) {
|
|
753
|
+
objectToOverride = extra;
|
|
754
|
+
}
|
|
755
|
+
else {
|
|
756
|
+
objectToOverride = name = {};
|
|
757
|
+
}
|
|
758
|
+
applyAfterNotify(objectToOverride);
|
|
759
|
+
_this.notify(noticeable, name, extra);
|
|
760
|
+
});
|
|
761
|
+
};
|
|
762
|
+
Client.prototype.makeNotice = function (noticeable, name, extra) {
|
|
763
|
+
if (name === void 0) { name = undefined; }
|
|
764
|
+
if (extra === void 0) { extra = undefined; }
|
|
765
|
+
var notice = makeNotice(noticeable);
|
|
608
766
|
if (name && !(typeof name === 'object')) {
|
|
609
767
|
var n = String(name);
|
|
610
768
|
name = { name: n };
|
|
@@ -616,17 +774,18 @@
|
|
|
616
774
|
notice = mergeNotice(notice, extra);
|
|
617
775
|
}
|
|
618
776
|
if (objectIsEmpty(notice)) {
|
|
619
|
-
return
|
|
777
|
+
return null;
|
|
620
778
|
}
|
|
779
|
+
var context = this.__getStoreOrDefaultObject().context;
|
|
621
780
|
var noticeTags = this.__constructTags(notice.tags);
|
|
622
|
-
var contextTags = this.__constructTags(
|
|
781
|
+
var contextTags = this.__constructTags(context["tags"]);
|
|
623
782
|
var configTags = this.__constructTags(this.config.tags);
|
|
624
783
|
// Turning into a Set will remove duplicates
|
|
625
784
|
var tags = noticeTags.concat(contextTags).concat(configTags);
|
|
626
785
|
var uniqueTags = tags.filter(function (item, index) { return tags.indexOf(item) === index; });
|
|
627
786
|
notice = merge(notice, {
|
|
628
787
|
name: notice.name || 'Error',
|
|
629
|
-
context: merge(
|
|
788
|
+
context: merge(context, notice.context),
|
|
630
789
|
projectRoot: notice.projectRoot || this.config.projectRoot,
|
|
631
790
|
environment: notice.environment || this.config.environment,
|
|
632
791
|
component: notice.component || this.config.component,
|
|
@@ -640,52 +799,40 @@
|
|
|
640
799
|
backtraceShift = 2;
|
|
641
800
|
}
|
|
642
801
|
notice.backtrace = makeBacktrace(notice.stack, backtraceShift);
|
|
643
|
-
|
|
644
|
-
return false;
|
|
645
|
-
}
|
|
646
|
-
this.addBreadcrumb('Honeybadger Notice', {
|
|
647
|
-
category: 'notice',
|
|
648
|
-
metadata: {
|
|
649
|
-
message: notice.message,
|
|
650
|
-
name: notice.name,
|
|
651
|
-
stack: notice.stack
|
|
652
|
-
}
|
|
653
|
-
});
|
|
654
|
-
notice.__breadcrumbs = this.config.breadcrumbsEnabled ? this.__breadcrumbs.slice() : [];
|
|
655
|
-
return this.__send(notice);
|
|
802
|
+
return notice;
|
|
656
803
|
};
|
|
657
804
|
Client.prototype.addBreadcrumb = function (message, opts) {
|
|
658
805
|
if (!this.config.breadcrumbsEnabled) {
|
|
659
806
|
return;
|
|
660
807
|
}
|
|
661
808
|
opts = opts || {};
|
|
662
|
-
var metadata =
|
|
809
|
+
var metadata = shallowClone(opts.metadata);
|
|
663
810
|
var category = opts.category || 'custom';
|
|
664
811
|
var timestamp = new Date().toISOString();
|
|
665
|
-
this.
|
|
812
|
+
var store = this.__store.getStore();
|
|
813
|
+
var breadcrumbs = store.breadcrumbs;
|
|
814
|
+
breadcrumbs.push({
|
|
666
815
|
category: category,
|
|
667
816
|
message: message,
|
|
668
817
|
metadata: metadata,
|
|
669
818
|
timestamp: timestamp
|
|
670
819
|
});
|
|
671
820
|
var limit = this.config.maxBreadcrumbs;
|
|
672
|
-
if (
|
|
673
|
-
|
|
821
|
+
if (breadcrumbs.length > limit) {
|
|
822
|
+
breadcrumbs = breadcrumbs.slice(breadcrumbs.length - limit);
|
|
674
823
|
}
|
|
824
|
+
store.breadcrumbs = breadcrumbs;
|
|
675
825
|
return this;
|
|
676
826
|
};
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
return this.config.reportData;
|
|
827
|
+
Client.prototype.__developmentMode = function () {
|
|
828
|
+
if (this.config.reportData === true) {
|
|
829
|
+
return false;
|
|
681
830
|
}
|
|
682
|
-
return
|
|
831
|
+
return (this.config.environment && this.config.developmentEnvironments.includes(this.config.environment));
|
|
683
832
|
};
|
|
684
|
-
/** @internal */
|
|
685
833
|
Client.prototype.__send = function (_notice) {
|
|
686
834
|
throw (new Error('Must implement send in subclass'));
|
|
687
835
|
};
|
|
688
|
-
/** @internal */
|
|
689
836
|
Client.prototype.__buildPayload = function (notice) {
|
|
690
837
|
var headers = filter(notice.headers, this.config.filters) || {};
|
|
691
838
|
var cgiData = filter(__assign(__assign({}, notice.cgiData), formatCGIData(headers, 'HTTP_')), this.config.filters);
|
|
@@ -721,14 +868,22 @@
|
|
|
721
868
|
details: notice.details || {}
|
|
722
869
|
};
|
|
723
870
|
};
|
|
724
|
-
/** @internal */
|
|
725
871
|
Client.prototype.__constructTags = function (tags) {
|
|
726
872
|
if (!tags) {
|
|
727
873
|
return [];
|
|
728
874
|
}
|
|
729
|
-
return tags.toString().split(TAG_SEPARATOR).
|
|
730
|
-
|
|
731
|
-
|
|
875
|
+
return tags.toString().split(TAG_SEPARATOR).filter(function (tag) { return NOT_BLANK.test(tag); });
|
|
876
|
+
};
|
|
877
|
+
/**
|
|
878
|
+
* For ALS, the store may be uninitialized (if .run()` has not been called).
|
|
879
|
+
* This provides an easy way to read the existing store object or fall back to a default.
|
|
880
|
+
* Returns *a copy* of the store.
|
|
881
|
+
* @internal
|
|
882
|
+
*/
|
|
883
|
+
Client.prototype.__getStoreOrDefaultObject = function () {
|
|
884
|
+
var existingStore = this.__store.getStore();
|
|
885
|
+
var store = existingStore || {};
|
|
886
|
+
return __assign({ context: {}, breadcrumbs: [] }, store);
|
|
732
887
|
};
|
|
733
888
|
return Client;
|
|
734
889
|
}());
|
|
@@ -748,23 +903,23 @@
|
|
|
748
903
|
return '';
|
|
749
904
|
}
|
|
750
905
|
if (element.id) {
|
|
751
|
-
name += "#"
|
|
906
|
+
name += "#".concat(element.id);
|
|
752
907
|
}
|
|
753
908
|
var stringClassNames = element.getAttribute('class');
|
|
754
909
|
if (stringClassNames) {
|
|
755
910
|
stringClassNames.split(/\s+/).forEach(function (className) {
|
|
756
|
-
name += "."
|
|
911
|
+
name += ".".concat(className);
|
|
757
912
|
});
|
|
758
913
|
}
|
|
759
914
|
['alt', 'name', 'title', 'type'].forEach(function (attrName) {
|
|
760
915
|
var attr = element.getAttribute(attrName);
|
|
761
916
|
if (attr) {
|
|
762
|
-
name += "["
|
|
917
|
+
name += "[".concat(attrName, "=\"").concat(attr, "\"]");
|
|
763
918
|
}
|
|
764
919
|
});
|
|
765
920
|
var siblings = getSiblings(element);
|
|
766
921
|
if (siblings.length > 1) {
|
|
767
|
-
name += ":nth-child("
|
|
922
|
+
name += ":nth-child(".concat(Array.prototype.indexOf.call(siblings, element) + 1, ")");
|
|
768
923
|
}
|
|
769
924
|
return name;
|
|
770
925
|
}
|
|
@@ -773,7 +928,7 @@
|
|
|
773
928
|
if (element.parentNode && element.parentNode.tagName) {
|
|
774
929
|
var parentName = stringSelectorOfElement(element.parentNode);
|
|
775
930
|
if (parentName.length > 0) {
|
|
776
|
-
return parentName
|
|
931
|
+
return "".concat(parentName, " > ").concat(name);
|
|
777
932
|
}
|
|
778
933
|
}
|
|
779
934
|
return name;
|
|
@@ -833,7 +988,7 @@
|
|
|
833
988
|
return parsed.pathname;
|
|
834
989
|
}
|
|
835
990
|
// x-domain
|
|
836
|
-
return parsed.protocol
|
|
991
|
+
return "".concat(parsed.protocol, "://").concat(parsed.host).concat(parsed.pathname);
|
|
837
992
|
}
|
|
838
993
|
function decodeCookie(string) {
|
|
839
994
|
var result = {};
|
|
@@ -921,12 +1076,12 @@
|
|
|
921
1076
|
ignoreOnError -= 1;
|
|
922
1077
|
return;
|
|
923
1078
|
}
|
|
924
|
-
|
|
925
|
-
return;
|
|
926
|
-
}
|
|
1079
|
+
// See https://developer.mozilla.org/en/docs/Web/API/GlobalEventHandlers/onerror#Notes
|
|
927
1080
|
if (line === 0 && /Script error\.?/.test(msg)) {
|
|
928
|
-
|
|
929
|
-
|
|
1081
|
+
if (client.config.enableUncaught) {
|
|
1082
|
+
// Log only if the user wants to report uncaught errors
|
|
1083
|
+
client.logger.warn('Ignoring cross-domain script error: enable CORS to track these types of errors', arguments);
|
|
1084
|
+
}
|
|
930
1085
|
return;
|
|
931
1086
|
}
|
|
932
1087
|
var notice = makeNotice(err);
|
|
@@ -940,7 +1095,7 @@
|
|
|
940
1095
|
// Simulate v8 stack
|
|
941
1096
|
notice.stack = [notice.message, '\n at ? (', url || 'unknown', ':', line || 0, ':', col || 0, ')'].join('');
|
|
942
1097
|
}
|
|
943
|
-
client.addBreadcrumb((notice.name === 'window.onerror' || !notice.name) ? 'window.onerror' : "window.onerror: "
|
|
1098
|
+
client.addBreadcrumb((notice.name === 'window.onerror' || !notice.name) ? 'window.onerror' : "window.onerror: ".concat(notice.name), {
|
|
944
1099
|
category: 'error',
|
|
945
1100
|
metadata: {
|
|
946
1101
|
name: notice.name,
|
|
@@ -948,7 +1103,9 @@
|
|
|
948
1103
|
stack: notice.stack
|
|
949
1104
|
}
|
|
950
1105
|
});
|
|
951
|
-
client.
|
|
1106
|
+
if (client.config.enableUncaught) {
|
|
1107
|
+
client.notify(notice);
|
|
1108
|
+
}
|
|
952
1109
|
};
|
|
953
1110
|
return function (msg, url, line, col, err) {
|
|
954
1111
|
onerror(msg, url, line, col, err);
|
|
@@ -986,14 +1143,14 @@
|
|
|
986
1143
|
// const lineNumber = reason.lineNumber || 0
|
|
987
1144
|
var fileName = 'unknown';
|
|
988
1145
|
var lineNumber = 0;
|
|
989
|
-
var stackFallback = reason.message
|
|
1146
|
+
var stackFallback = "".concat(reason.message, "\n at ? (").concat(fileName, ":").concat(lineNumber, ")");
|
|
990
1147
|
var stack = reason.stack || stackFallback;
|
|
991
1148
|
var err = {
|
|
992
1149
|
name: reason.name,
|
|
993
|
-
message: "UnhandledPromiseRejectionWarning: "
|
|
1150
|
+
message: "UnhandledPromiseRejectionWarning: ".concat(reason),
|
|
994
1151
|
stack: stack
|
|
995
1152
|
};
|
|
996
|
-
client.addBreadcrumb("window.onunhandledrejection: "
|
|
1153
|
+
client.addBreadcrumb("window.onunhandledrejection: ".concat(err.name), {
|
|
997
1154
|
category: 'error',
|
|
998
1155
|
metadata: err
|
|
999
1156
|
});
|
|
@@ -1003,7 +1160,7 @@
|
|
|
1003
1160
|
var message = typeof reason === 'string' ? reason : ((_a = JSON.stringify(reason)) !== null && _a !== void 0 ? _a : 'Unspecified reason');
|
|
1004
1161
|
client.notify({
|
|
1005
1162
|
name: 'window.onunhandledrejection',
|
|
1006
|
-
message: "UnhandledPromiseRejectionWarning: "
|
|
1163
|
+
message: "UnhandledPromiseRejectionWarning: ".concat(message)
|
|
1007
1164
|
});
|
|
1008
1165
|
}
|
|
1009
1166
|
return function (promiseRejectionEvent) {
|
|
@@ -1112,7 +1269,7 @@
|
|
|
1112
1269
|
var xhr = this;
|
|
1113
1270
|
var url = arguments[1];
|
|
1114
1271
|
var method = typeof arguments[0] === 'string' ? arguments[0].toUpperCase() : arguments[0];
|
|
1115
|
-
var message = method
|
|
1272
|
+
var message = "".concat(method, " ").concat(localURLPathname(url));
|
|
1116
1273
|
this.__hb_xhr = {
|
|
1117
1274
|
type: 'xhr',
|
|
1118
1275
|
method: method,
|
|
@@ -1197,7 +1354,7 @@
|
|
|
1197
1354
|
if (typeof method === 'string') {
|
|
1198
1355
|
method = method.toUpperCase();
|
|
1199
1356
|
}
|
|
1200
|
-
var message = method
|
|
1357
|
+
var message = "".concat(method, " ").concat(localURLPathname(url));
|
|
1201
1358
|
var metadata = {
|
|
1202
1359
|
type: 'fetch',
|
|
1203
1360
|
method: method,
|
|
@@ -1310,7 +1467,7 @@
|
|
|
1310
1467
|
var prototype = _window[prop] && _window[prop].prototype;
|
|
1311
1468
|
if (prototype && Object.prototype.hasOwnProperty.call(prototype, 'addEventListener')) {
|
|
1312
1469
|
instrument(prototype, 'addEventListener', function (original) {
|
|
1313
|
-
var wrapOpts = { component: prop
|
|
1470
|
+
var wrapOpts = { component: "".concat(prop, ".prototype.addEventListener") };
|
|
1314
1471
|
// See https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
|
|
1315
1472
|
return function (type, listener, useCapture, wantsUntrusted) {
|
|
1316
1473
|
try {
|
|
@@ -1401,10 +1558,6 @@
|
|
|
1401
1558
|
var _this = this;
|
|
1402
1559
|
this.__incrementErrorsCount();
|
|
1403
1560
|
var payload = this.__buildPayload(notice);
|
|
1404
|
-
var handlers = Array.prototype.slice.call(this.__afterNotifyHandlers);
|
|
1405
|
-
if (notice.afterNotify) {
|
|
1406
|
-
handlers.unshift(notice.afterNotify);
|
|
1407
|
-
}
|
|
1408
1561
|
try {
|
|
1409
1562
|
var x_1 = new XMLHttpRequest();
|
|
1410
1563
|
x_1.open('POST', endpoint(this.config, '/v1/notices/js'), this.config.async);
|
|
@@ -1414,21 +1567,21 @@
|
|
|
1414
1567
|
x_1.send(JSON.stringify(sanitize(payload, this.config.maxObjectDepth)));
|
|
1415
1568
|
x_1.onload = function () {
|
|
1416
1569
|
if (x_1.status !== 201) {
|
|
1417
|
-
runAfterNotifyHandlers(notice,
|
|
1418
|
-
_this.logger.debug("Unable to send error report: "
|
|
1570
|
+
runAfterNotifyHandlers(notice, _this.__afterNotifyHandlers, new Error("Bad HTTP response: ".concat(x_1.status)));
|
|
1571
|
+
_this.logger.debug("Unable to send error report: ".concat(x_1.status, ": ").concat(x_1.statusText), x_1, notice);
|
|
1419
1572
|
return;
|
|
1420
1573
|
}
|
|
1574
|
+
var uuid = JSON.parse(x_1.response).id;
|
|
1421
1575
|
runAfterNotifyHandlers(merge(notice, {
|
|
1422
|
-
id:
|
|
1423
|
-
}),
|
|
1424
|
-
_this.logger.debug(
|
|
1576
|
+
id: uuid
|
|
1577
|
+
}), _this.__afterNotifyHandlers);
|
|
1578
|
+
_this.logger.debug("Error report sent \u26A1 https://app.honeybadger.io/notice/".concat(uuid));
|
|
1425
1579
|
};
|
|
1426
1580
|
}
|
|
1427
1581
|
catch (err) {
|
|
1428
|
-
runAfterNotifyHandlers(notice,
|
|
1582
|
+
runAfterNotifyHandlers(notice, this.__afterNotifyHandlers, err);
|
|
1429
1583
|
this.logger.error('Unable to send error report: error while initializing request', err, notice);
|
|
1430
1584
|
}
|
|
1431
|
-
return true;
|
|
1432
1585
|
};
|
|
1433
1586
|
/**
|
|
1434
1587
|
* wrap always returns the same function so that callbacks can be removed via
|
|
@@ -1452,14 +1605,7 @@
|
|
|
1452
1605
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
1453
1606
|
var client_1 = this;
|
|
1454
1607
|
func.___hb = function () {
|
|
1455
|
-
|
|
1456
|
-
// Catch if:
|
|
1457
|
-
// 1. We explicitly want to catch (i.e. if the error could be
|
|
1458
|
-
// caught before reaching window.onerror)
|
|
1459
|
-
// 2. The browser provides less information via the window.onerror
|
|
1460
|
-
// handler
|
|
1461
|
-
// 3. The window.onerror handler is unavailable
|
|
1462
|
-
if (opts.catch || preferCatch || !onErrorEnabled) {
|
|
1608
|
+
if (preferCatch) {
|
|
1463
1609
|
try {
|
|
1464
1610
|
// eslint-disable-next-line prefer-rest-params
|
|
1465
1611
|
return func.apply(this, arguments);
|
|
@@ -1470,7 +1616,7 @@
|
|
|
1470
1616
|
}
|
|
1471
1617
|
client_1.__lastWrapErr = err;
|
|
1472
1618
|
ignoreNextOnError();
|
|
1473
|
-
client_1.addBreadcrumb(opts.component ? opts.component
|
|
1619
|
+
client_1.addBreadcrumb(opts.component ? "".concat(opts.component, ": ").concat(err.name) : err.name, {
|
|
1474
1620
|
category: 'error',
|
|
1475
1621
|
metadata: {
|
|
1476
1622
|
message: err.message,
|
|
@@ -1478,7 +1624,9 @@
|
|
|
1478
1624
|
stack: err.stack
|
|
1479
1625
|
}
|
|
1480
1626
|
});
|
|
1481
|
-
client_1.
|
|
1627
|
+
if (client_1.config.enableUncaught) {
|
|
1628
|
+
client_1.notify(err);
|
|
1629
|
+
}
|
|
1482
1630
|
throw (err);
|
|
1483
1631
|
}
|
|
1484
1632
|
}
|
|
@@ -1517,5 +1665,5 @@
|
|
|
1517
1665
|
|
|
1518
1666
|
return browser;
|
|
1519
1667
|
|
|
1520
|
-
}))
|
|
1668
|
+
}));
|
|
1521
1669
|
//# sourceMappingURL=honeybadger.js.map
|