@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.
@@ -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).map(function (line) {
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
- return false;
259
+ result = false;
239
260
  }
240
261
  }
241
- return true;
262
+ return result;
242
263
  }
243
264
  function runAfterNotifyHandlers(notice, handlers, error) {
244
- if (error === void 0) { error = undefined; }
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 newObject(obj) {
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
- // Functions are TMI and Symbols can't convert to strings.
279
- if (/function|symbol/.test(typeof (obj))) {
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] " + e;
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' && !client.config.debug) {
342
- return;
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 = newObject(thing);
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 + "/" + path;
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) { return filter(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 + "=" + value, key + "=[FILTERED]");
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: '3.2.8'
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
- /** @internal */
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'], disabled: false, debug: false, tags: null, enableUncaught: true, enableUnhandledRejection: true, afterUncaught: function () { return true; }, filters: ['creditcard', 'password'], __plugins: [] }, opts);
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
- this.__context = merge(this.__context, context);
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
- this.__context = merge({}, context);
652
+ store.context = context;
581
653
  }
582
654
  else {
583
- this.__context = {};
655
+ store.context = {};
584
656
  }
585
657
  return this;
586
658
  };
587
659
  Client.prototype.clear = function () {
588
- this.__context = {};
589
- this.__breadcrumbs = [];
660
+ var store = this.__store.getStore();
661
+ store.context = {};
662
+ store.breadcrumbs = [];
590
663
  return this;
591
664
  };
592
- Client.prototype.notify = function (notice, name, extra) {
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
- if (this.config.disabled) {
596
- this.logger.warn('Deprecation warning: instead of `disabled: true`, use `reportData: false` to explicitly disable Honeybadger reporting. (Dropping notice: honeybadger.js is disabled)');
597
- return false;
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.__reportData()) {
600
- this.logger.debug('Dropping notice: honeybadger.js is in development mode');
601
- return false;
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.config.apiKey) {
604
- this.logger.warn('Unable to send error report: no API key has been configured');
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
- notice = makeNotice(notice);
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 false;
777
+ return null;
620
778
  }
779
+ var context = this.__getStoreOrDefaultObject().context;
621
780
  var noticeTags = this.__constructTags(notice.tags);
622
- var contextTags = this.__constructTags(this.__context["tags"]);
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(this.__context, notice.context),
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
- if (!runBeforeNotifyHandlers(notice, this.__beforeNotifyHandlers)) {
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 = newObject(opts.metadata);
809
+ var metadata = shallowClone(opts.metadata);
663
810
  var category = opts.category || 'custom';
664
811
  var timestamp = new Date().toISOString();
665
- this.__breadcrumbs.push({
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 (this.__breadcrumbs.length > limit) {
673
- this.__breadcrumbs = this.__breadcrumbs.slice(this.__breadcrumbs.length - limit);
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
- /** @internal */
678
- Client.prototype.__reportData = function () {
679
- if (this.config.reportData !== null) {
680
- return this.config.reportData;
827
+ Client.prototype.__developmentMode = function () {
828
+ if (this.config.reportData === true) {
829
+ return false;
681
830
  }
682
- return !(this.config.environment && this.config.developmentEnvironments.includes(this.config.environment));
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).map(function (tag) {
730
- return tag.replace(TAG_SANITIZER, STRING_EMPTY);
731
- }).filter(function (tag) { return NOT_BLANK.test(tag); });
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 += "#" + element.id;
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 += "." + className;
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 += "[" + attrName + "=\"" + attr + "\"]";
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(" + (Array.prototype.indexOf.call(siblings, element) + 1) + ")";
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 + " > " + name;
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 + "://" + parsed.host + parsed.pathname;
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
- if (!client.config.enableUncaught) {
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
- // See https://developer.mozilla.org/en/docs/Web/API/GlobalEventHandlers/onerror#Notes
929
- client.logger.info('Ignoring cross-domain script error: enable CORS to track these types of errors', arguments);
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: " + notice.name, {
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.notify(notice);
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 + "\n at ? (" + fileName + ":" + lineNumber + ")";
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: " + reason,
1150
+ message: "UnhandledPromiseRejectionWarning: ".concat(reason),
994
1151
  stack: stack
995
1152
  };
996
- client.addBreadcrumb("window.onunhandledrejection: " + err.name, {
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: " + message
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 + " " + localURLPathname(url);
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 + " " + localURLPathname(url);
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 + ".prototype.addEventListener" };
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, handlers, new Error("Bad HTTP response: " + x_1.status));
1418
- _this.logger.debug("Unable to send error report: " + x_1.status + ": " + x_1.statusText, x_1, notice);
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: JSON.parse(x_1.response).id
1423
- }), handlers);
1424
- _this.logger.debug('Error report sent', notice);
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, handlers, err);
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
- var onErrorEnabled = client_1.config.enableUncaught;
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 + ": " + err.name : err.name, {
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.notify(err);
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