@honeybadger-io/js 3.2.7 → 4.0.0-beta.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.
Files changed (38) hide show
  1. package/dist/browser/honeybadger.js +267 -116
  2. package/dist/browser/honeybadger.js.map +1 -1
  3. package/dist/browser/honeybadger.min.js +1 -1
  4. package/dist/browser/honeybadger.min.js.map +1 -1
  5. package/dist/browser/types/browser/util.d.ts +1 -1
  6. package/dist/browser/types/core/client.d.ts +23 -3
  7. package/dist/browser/types/core/error.d.ts +3 -0
  8. package/dist/browser/types/core/store.d.ts +7 -0
  9. package/dist/browser/types/core/types.d.ts +8 -4
  10. package/dist/browser/types/core/util.d.ts +4 -2
  11. package/dist/browser/types/server/async_store.d.ts +5 -0
  12. package/dist/browser/types/server/aws_lambda.d.ts +9 -0
  13. package/dist/browser/types/server/integrations/uncaught_exception.d.ts +2 -0
  14. package/dist/browser/types/server/integrations/unhandled_rejection.d.ts +2 -0
  15. package/dist/browser/types/server/middleware.d.ts +4 -0
  16. package/dist/browser/types/server/util.d.ts +9 -0
  17. package/dist/browser/types/server.d.ts +14 -0
  18. package/dist/server/honeybadger.d.ts +3 -1
  19. package/dist/server/honeybadger.js +375 -139
  20. package/dist/server/types/browser/integrations/breadcrumbs.d.ts +2 -0
  21. package/dist/server/types/browser/integrations/event_listeners.d.ts +2 -0
  22. package/dist/server/types/browser/integrations/onerror.d.ts +3 -0
  23. package/dist/server/types/browser/integrations/onunhandledrejection.d.ts +2 -0
  24. package/dist/server/types/browser/integrations/timers.d.ts +2 -0
  25. package/dist/server/types/browser/util.d.ts +18 -0
  26. package/dist/server/types/browser.d.ts +15 -0
  27. package/dist/server/types/core/client.d.ts +23 -3
  28. package/dist/server/types/core/error.d.ts +3 -0
  29. package/dist/server/types/core/store.d.ts +7 -0
  30. package/dist/server/types/core/types.d.ts +8 -4
  31. package/dist/server/types/core/util.d.ts +4 -2
  32. package/dist/server/types/server/async_store.d.ts +5 -0
  33. package/dist/server/types/server/aws_lambda.d.ts +9 -0
  34. package/dist/server/types/server/middleware.d.ts +3 -5
  35. package/dist/server/types/server/util.d.ts +7 -0
  36. package/dist/server/types/server.d.ts +3 -1
  37. package/honeybadger.d.ts +2 -1
  38. package/package.json +25 -22
@@ -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,17 +232,39 @@
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
  }
@@ -303,7 +326,7 @@
303
326
  }
304
327
  // Serialize inside arrays
305
328
  if (Array.isArray(obj)) {
306
- return obj.map(function (o) { return serialize(o, depth + 1); });
329
+ return obj.map(function (o) { return safeSerialize(o, depth + 1); });
307
330
  }
308
331
  // Serialize inside objects
309
332
  if (typeof (obj) === 'object') {
@@ -311,7 +334,7 @@
311
334
  for (var k in obj) {
312
335
  var v = obj[k];
313
336
  if (Object.prototype.hasOwnProperty.call(obj, k) && (k != null) && (v != null)) {
314
- ret[k] = serialize(v, depth + 1);
337
+ ret[k] = safeSerialize(v, depth + 1);
315
338
  }
316
339
  }
317
340
  return ret;
@@ -319,7 +342,16 @@
319
342
  // Return everything else untouched
320
343
  return obj;
321
344
  }
322
- return serialize(obj);
345
+ function safeSerialize(obj, depth) {
346
+ if (depth === void 0) { depth = 0; }
347
+ try {
348
+ return serialize(obj, depth);
349
+ }
350
+ catch (e) {
351
+ return "[ERROR] ".concat(e);
352
+ }
353
+ }
354
+ return safeSerialize(obj);
323
355
  }
324
356
  function logger(client) {
325
357
  var log = function (method) {
@@ -329,8 +361,13 @@
329
361
  for (var _i = 0; _i < arguments.length; _i++) {
330
362
  args[_i] = arguments[_i];
331
363
  }
332
- if (method === 'debug' && !client.config.debug) {
333
- return;
364
+ if (method === 'debug') {
365
+ if (!client.config.debug) {
366
+ return;
367
+ }
368
+ // Log at default level so that you don't need to also enable verbose
369
+ // logging in Chrome.
370
+ method = 'log';
334
371
  }
335
372
  args.unshift('[Honeybadger]');
336
373
  (_a = client.config.logger)[method].apply(_a, args);
@@ -353,7 +390,7 @@
353
390
  if (!thing) {
354
391
  notice = {};
355
392
  }
356
- else if (Object.prototype.toString.call(thing) === '[object Error]') {
393
+ else if (thing instanceof Error || Object.prototype.toString.call(thing) === '[object Error]') {
357
394
  var e = thing;
358
395
  notice = merge(thing, { name: e.name, message: e.message, stack: e.stack });
359
396
  }
@@ -394,7 +431,7 @@
394
431
  function endpoint(config, path) {
395
432
  var endpoint = config.endpoint.trim().replace(/\/$/, '');
396
433
  path = path.trim().replace(/(^\/|\/$)/g, '');
397
- return endpoint + "/" + path;
434
+ return "".concat(endpoint, "/").concat(path);
398
435
  }
399
436
  function generateStackTrace() {
400
437
  try {
@@ -453,7 +490,9 @@
453
490
  return newObj;
454
491
  }
455
492
  if (is('Array', obj)) {
456
- return obj.map(function (v) { return filter(v); });
493
+ return obj.map(function (v) {
494
+ return filter(v);
495
+ });
457
496
  }
458
497
  if (is('Function', obj)) {
459
498
  return '[FUNC]';
@@ -489,7 +528,7 @@
489
528
  query.split(/[&]\s?/).forEach(function (pair) {
490
529
  var _a = pair.split('=', 2), key = _a[0], value = _a[1];
491
530
  if (filterMatch(key, filters)) {
492
- result = result.replace(key + "=" + value, key + "=[FILTERED]");
531
+ result = result.replace("".concat(key, "=").concat(value), "".concat(key, "=[FILTERED]"));
493
532
  }
494
533
  });
495
534
  return result;
@@ -503,34 +542,64 @@
503
542
  });
504
543
  return formattedVars;
505
544
  }
545
+ function getSourceCodeSnippet(fileData, lineNumber, sourceRadius) {
546
+ if (sourceRadius === void 0) { sourceRadius = 2; }
547
+ if (!fileData) {
548
+ return null;
549
+ }
550
+ var lines = fileData.split('\n');
551
+ // add one empty line because array index starts from 0, but error line number is counted from 1
552
+ lines.unshift('');
553
+ var start = lineNumber - sourceRadius;
554
+ var end = lineNumber + sourceRadius;
555
+ var result = {};
556
+ for (var i = start; i <= end; i++) {
557
+ var line = lines[i];
558
+ if (typeof line === 'string') {
559
+ result[i] = line;
560
+ }
561
+ }
562
+ return result;
563
+ }
564
+
565
+ var GlobalStore = /** @class */ (function () {
566
+ function GlobalStore(store) {
567
+ this.store = store;
568
+ }
569
+ GlobalStore.prototype.getStore = function () {
570
+ return this.store;
571
+ };
572
+ GlobalStore.prototype.run = function (store, callback) {
573
+ var args = [];
574
+ for (var _i = 2; _i < arguments.length; _i++) {
575
+ args[_i - 2] = arguments[_i];
576
+ }
577
+ this.store = store;
578
+ return callback.apply(void 0, args);
579
+ };
580
+ return GlobalStore;
581
+ }());
506
582
 
507
583
  var notifier = {
508
584
  name: 'honeybadger-js',
509
585
  url: 'https://github.com/honeybadger-io/honeybadger-js',
510
- version: '3.2.7'
586
+ version: '4.0.0-beta.1'
511
587
  };
512
- // Split at commas
513
- var TAG_SEPARATOR = /,/;
514
- // Removes any non-word characters
515
- var TAG_SANITIZER = /[^\w]/g;
516
- // Checks for blank strings
517
- var STRING_EMPTY = '';
588
+ // Split at commas and spaces
589
+ var TAG_SEPARATOR = /,|\s+/;
518
590
  // Checks for non-blank characters
519
591
  var NOT_BLANK = /\S/;
520
592
  var Client = /** @class */ (function () {
521
593
  function Client(opts) {
522
594
  if (opts === void 0) { opts = {}; }
523
- /** @internal */
524
595
  this.__pluginsExecuted = false;
525
- /** @internal */
526
- this.__context = {};
527
- /** @internal */
528
- this.__breadcrumbs = [];
529
- /** @internal */
596
+ this.__store = null;
530
597
  this.__beforeNotifyHandlers = [];
531
- /** @internal */
532
598
  this.__afterNotifyHandlers = [];
533
- 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);
599
+ 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);
600
+ // First, we go with the global (shared) store.
601
+ // Webserver middleware can then switch to the AsyncStore for async context tracking.
602
+ this.__store = new GlobalStore({ context: {}, breadcrumbs: [] });
534
603
  this.logger = logger(this);
535
604
  }
536
605
  Client.prototype.factory = function (_opts) {
@@ -551,6 +620,10 @@
551
620
  }
552
621
  return this;
553
622
  };
623
+ /** @internal */
624
+ Client.prototype.__setStore = function (store) {
625
+ this.__store = store;
626
+ };
554
627
  Client.prototype.beforeNotify = function (handler) {
555
628
  this.__beforeNotifyHandlers.push(handler);
556
629
  return this;
@@ -561,41 +634,129 @@
561
634
  };
562
635
  Client.prototype.setContext = function (context) {
563
636
  if (typeof context === 'object') {
564
- this.__context = merge(this.__context, context);
637
+ var store = this.__store.getStore();
638
+ store.context = merge(store.context, context);
565
639
  }
566
640
  return this;
567
641
  };
568
642
  Client.prototype.resetContext = function (context) {
569
643
  this.logger.warn('Deprecation warning: `Honeybadger.resetContext()` has been deprecated; please use `Honeybadger.clear()` instead.');
644
+ var store = this.__store.getStore();
570
645
  if (typeof context === 'object' && context !== null) {
571
- this.__context = merge({}, context);
646
+ store.context = context;
572
647
  }
573
648
  else {
574
- this.__context = {};
649
+ store.context = {};
575
650
  }
576
651
  return this;
577
652
  };
578
653
  Client.prototype.clear = function () {
579
- this.__context = {};
580
- this.__breadcrumbs = [];
654
+ var store = this.__store.getStore();
655
+ store.context = {};
656
+ store.breadcrumbs = [];
581
657
  return this;
582
658
  };
583
- Client.prototype.notify = function (notice, name, extra) {
659
+ Client.prototype.notify = function (noticeable, name, extra) {
660
+ var _this = this;
584
661
  if (name === void 0) { name = undefined; }
585
662
  if (extra === void 0) { extra = undefined; }
586
- if (this.config.disabled) {
587
- this.logger.warn('Deprecation warning: instead of `disabled: true`, use `reportData: false` to explicitly disable Honeybadger reporting. (Dropping notice: honeybadger.js is disabled)');
588
- return false;
663
+ var preConditionError = null;
664
+ var notice = this.makeNotice(noticeable, name, extra);
665
+ if (!notice) {
666
+ this.logger.debug('failed to build error report');
667
+ preConditionError = new Error('failed to build error report');
589
668
  }
590
- if (!this.__reportData()) {
591
- this.logger.debug('Dropping notice: honeybadger.js is in development mode');
592
- return false;
669
+ if (!preConditionError && this.config.reportData === false) {
670
+ this.logger.debug('skipping error report: honeybadger.js is disabled', notice);
671
+ preConditionError = new Error('honeybadger.js is disabled');
672
+ }
673
+ if (!preConditionError && this.__developmentMode()) {
674
+ this.logger.log('honeybadger.js is in development mode; the following error report will be sent in production.', notice);
675
+ preConditionError = new Error('honeybadger.js is in development mode');
593
676
  }
594
- if (!this.config.apiKey) {
595
- this.logger.warn('Unable to send error report: no API key has been configured');
677
+ if (!preConditionError && !this.config.apiKey) {
678
+ this.logger.warn('could not send error report: no API key has been configured', notice);
679
+ preConditionError = new Error('missing API key');
680
+ }
681
+ var beforeNotifyResult = runBeforeNotifyHandlers(notice, this.__beforeNotifyHandlers);
682
+ if (!preConditionError && !beforeNotifyResult) {
683
+ this.logger.debug('skipping error report: beforeNotify handlers returned false', notice);
684
+ preConditionError = new Error('beforeNotify handlers returned false');
685
+ }
686
+ if (preConditionError) {
687
+ runAfterNotifyHandlers(notice, this.__afterNotifyHandlers, preConditionError);
596
688
  return false;
597
689
  }
598
- notice = makeNotice(notice);
690
+ this.addBreadcrumb('Honeybadger Notice', {
691
+ category: 'notice',
692
+ metadata: {
693
+ message: notice.message,
694
+ name: notice.name,
695
+ stack: notice.stack
696
+ }
697
+ });
698
+ var breadcrumbs = this.__getStoreOrDefaultObject().breadcrumbs;
699
+ notice.__breadcrumbs = this.config.breadcrumbsEnabled ? breadcrumbs.slice() : [];
700
+ // we need to have the source file data before the beforeNotifyHandlers,
701
+ // in case they modify them
702
+ var sourceCodeData = notice && notice.backtrace ? notice.backtrace.map(function (trace) { return newObject(trace); }) : null;
703
+ getSourceForBacktrace(sourceCodeData, this.__getSourceFileHandler, function (sourcePerTrace) {
704
+ sourcePerTrace.forEach(function (source, index) {
705
+ notice.backtrace[index].source = source;
706
+ });
707
+ _this.__send(notice);
708
+ });
709
+ return true;
710
+ };
711
+ /**
712
+ * An async version of {@link notify} that resolves only after the notice has been reported to Honeybadger.
713
+ * Implemented using the {@link afterNotify} hook.
714
+ * Rejects if for any reason the report failed to be reported.
715
+ * Useful in serverless environments (AWS Lambda).
716
+ */
717
+ Client.prototype.notifyAsync = function (noticeable, name, extra) {
718
+ var _this = this;
719
+ if (name === void 0) { name = undefined; }
720
+ if (extra === void 0) { extra = undefined; }
721
+ return new Promise(function (resolve, reject) {
722
+ var applyAfterNotify = function (partialNotice) {
723
+ var originalAfterNotify = partialNotice.afterNotify;
724
+ partialNotice.afterNotify = function (err) {
725
+ originalAfterNotify === null || originalAfterNotify === void 0 ? void 0 : originalAfterNotify.call(_this, err);
726
+ if (err) {
727
+ return reject(err);
728
+ }
729
+ resolve();
730
+ };
731
+ };
732
+ // We have to respect any afterNotify hooks that come from the arguments
733
+ var objectToOverride;
734
+ if (noticeable.afterNotify) {
735
+ objectToOverride = noticeable;
736
+ }
737
+ else if (name && name.afterNotify) {
738
+ objectToOverride = name;
739
+ }
740
+ else if (extra && extra.afterNotify) {
741
+ objectToOverride = extra;
742
+ }
743
+ else if (name && typeof name === 'object') {
744
+ objectToOverride = name;
745
+ }
746
+ else if (extra) {
747
+ objectToOverride = extra;
748
+ }
749
+ else {
750
+ objectToOverride = name = {};
751
+ }
752
+ applyAfterNotify(objectToOverride);
753
+ _this.notify(noticeable, name, extra);
754
+ });
755
+ };
756
+ Client.prototype.makeNotice = function (noticeable, name, extra) {
757
+ if (name === void 0) { name = undefined; }
758
+ if (extra === void 0) { extra = undefined; }
759
+ var notice = makeNotice(noticeable);
599
760
  if (name && !(typeof name === 'object')) {
600
761
  var n = String(name);
601
762
  name = { name: n };
@@ -607,17 +768,18 @@
607
768
  notice = mergeNotice(notice, extra);
608
769
  }
609
770
  if (objectIsEmpty(notice)) {
610
- return false;
771
+ return null;
611
772
  }
773
+ var context = this.__getStoreOrDefaultObject().context;
612
774
  var noticeTags = this.__constructTags(notice.tags);
613
- var contextTags = this.__constructTags(this.__context["tags"]);
775
+ var contextTags = this.__constructTags(context["tags"]);
614
776
  var configTags = this.__constructTags(this.config.tags);
615
777
  // Turning into a Set will remove duplicates
616
778
  var tags = noticeTags.concat(contextTags).concat(configTags);
617
779
  var uniqueTags = tags.filter(function (item, index) { return tags.indexOf(item) === index; });
618
780
  notice = merge(notice, {
619
781
  name: notice.name || 'Error',
620
- context: merge(this.__context, notice.context),
782
+ context: merge(context, notice.context),
621
783
  projectRoot: notice.projectRoot || this.config.projectRoot,
622
784
  environment: notice.environment || this.config.environment,
623
785
  component: notice.component || this.config.component,
@@ -631,19 +793,7 @@
631
793
  backtraceShift = 2;
632
794
  }
633
795
  notice.backtrace = makeBacktrace(notice.stack, backtraceShift);
634
- if (!runBeforeNotifyHandlers(notice, this.__beforeNotifyHandlers)) {
635
- return false;
636
- }
637
- this.addBreadcrumb('Honeybadger Notice', {
638
- category: 'notice',
639
- metadata: {
640
- message: notice.message,
641
- name: notice.name,
642
- stack: notice.stack
643
- }
644
- });
645
- notice.__breadcrumbs = this.config.breadcrumbsEnabled ? this.__breadcrumbs.slice() : [];
646
- return this.__send(notice);
796
+ return notice;
647
797
  };
648
798
  Client.prototype.addBreadcrumb = function (message, opts) {
649
799
  if (!this.config.breadcrumbsEnabled) {
@@ -653,30 +803,30 @@
653
803
  var metadata = newObject(opts.metadata);
654
804
  var category = opts.category || 'custom';
655
805
  var timestamp = new Date().toISOString();
656
- this.__breadcrumbs.push({
806
+ var store = this.__store.getStore();
807
+ var breadcrumbs = store.breadcrumbs;
808
+ breadcrumbs.push({
657
809
  category: category,
658
810
  message: message,
659
811
  metadata: metadata,
660
812
  timestamp: timestamp
661
813
  });
662
814
  var limit = this.config.maxBreadcrumbs;
663
- if (this.__breadcrumbs.length > limit) {
664
- this.__breadcrumbs = this.__breadcrumbs.slice(this.__breadcrumbs.length - limit);
815
+ if (breadcrumbs.length > limit) {
816
+ breadcrumbs = breadcrumbs.slice(breadcrumbs.length - limit);
665
817
  }
818
+ store.breadcrumbs = breadcrumbs;
666
819
  return this;
667
820
  };
668
- /** @internal */
669
- Client.prototype.__reportData = function () {
670
- if (this.config.reportData !== null) {
671
- return this.config.reportData;
821
+ Client.prototype.__developmentMode = function () {
822
+ if (this.config.reportData === true) {
823
+ return false;
672
824
  }
673
- return !(this.config.environment && this.config.developmentEnvironments.includes(this.config.environment));
825
+ return (this.config.environment && this.config.developmentEnvironments.includes(this.config.environment));
674
826
  };
675
- /** @internal */
676
827
  Client.prototype.__send = function (_notice) {
677
828
  throw (new Error('Must implement send in subclass'));
678
829
  };
679
- /** @internal */
680
830
  Client.prototype.__buildPayload = function (notice) {
681
831
  var headers = filter(notice.headers, this.config.filters) || {};
682
832
  var cgiData = filter(__assign(__assign({}, notice.cgiData), formatCGIData(headers, 'HTTP_')), this.config.filters);
@@ -712,14 +862,22 @@
712
862
  details: notice.details || {}
713
863
  };
714
864
  };
715
- /** @internal */
716
865
  Client.prototype.__constructTags = function (tags) {
717
866
  if (!tags) {
718
867
  return [];
719
868
  }
720
- return tags.toString().split(TAG_SEPARATOR).map(function (tag) {
721
- return tag.replace(TAG_SANITIZER, STRING_EMPTY);
722
- }).filter(function (tag) { return NOT_BLANK.test(tag); });
869
+ return tags.toString().split(TAG_SEPARATOR).filter(function (tag) { return NOT_BLANK.test(tag); });
870
+ };
871
+ /**
872
+ * For ALS, the store may be uninitialized (if .run()` has not been called).
873
+ * This provides an easy way to read the existing store object or fall back to a default.
874
+ * Returns *a copy* of the store.
875
+ * @internal
876
+ */
877
+ Client.prototype.__getStoreOrDefaultObject = function () {
878
+ var existingStore = this.__store.getStore();
879
+ var store = existingStore || {};
880
+ return __assign({ context: {}, breadcrumbs: [] }, store);
723
881
  };
724
882
  return Client;
725
883
  }());
@@ -739,23 +897,23 @@
739
897
  return '';
740
898
  }
741
899
  if (element.id) {
742
- name += "#" + element.id;
900
+ name += "#".concat(element.id);
743
901
  }
744
902
  var stringClassNames = element.getAttribute('class');
745
903
  if (stringClassNames) {
746
904
  stringClassNames.split(/\s+/).forEach(function (className) {
747
- name += "." + className;
905
+ name += ".".concat(className);
748
906
  });
749
907
  }
750
908
  ['alt', 'name', 'title', 'type'].forEach(function (attrName) {
751
909
  var attr = element.getAttribute(attrName);
752
910
  if (attr) {
753
- name += "[" + attrName + "=\"" + attr + "\"]";
911
+ name += "[".concat(attrName, "=\"").concat(attr, "\"]");
754
912
  }
755
913
  });
756
914
  var siblings = getSiblings(element);
757
915
  if (siblings.length > 1) {
758
- name += ":nth-child(" + (Array.prototype.indexOf.call(siblings, element) + 1) + ")";
916
+ name += ":nth-child(".concat(Array.prototype.indexOf.call(siblings, element) + 1, ")");
759
917
  }
760
918
  return name;
761
919
  }
@@ -764,7 +922,7 @@
764
922
  if (element.parentNode && element.parentNode.tagName) {
765
923
  var parentName = stringSelectorOfElement(element.parentNode);
766
924
  if (parentName.length > 0) {
767
- return parentName + " > " + name;
925
+ return "".concat(parentName, " > ").concat(name);
768
926
  }
769
927
  }
770
928
  return name;
@@ -824,7 +982,7 @@
824
982
  return parsed.pathname;
825
983
  }
826
984
  // x-domain
827
- return parsed.protocol + "://" + parsed.host + parsed.pathname;
985
+ return "".concat(parsed.protocol, "://").concat(parsed.host).concat(parsed.pathname);
828
986
  }
829
987
  function decodeCookie(string) {
830
988
  var result = {};
@@ -912,12 +1070,12 @@
912
1070
  ignoreOnError -= 1;
913
1071
  return;
914
1072
  }
915
- if (!client.config.enableUncaught) {
916
- return;
917
- }
1073
+ // See https://developer.mozilla.org/en/docs/Web/API/GlobalEventHandlers/onerror#Notes
918
1074
  if (line === 0 && /Script error\.?/.test(msg)) {
919
- // See https://developer.mozilla.org/en/docs/Web/API/GlobalEventHandlers/onerror#Notes
920
- client.logger.info('Ignoring cross-domain script error: enable CORS to track these types of errors', arguments);
1075
+ if (client.config.enableUncaught) {
1076
+ // Log only if the user wants to report uncaught errors
1077
+ client.logger.warn('Ignoring cross-domain script error: enable CORS to track these types of errors', arguments);
1078
+ }
921
1079
  return;
922
1080
  }
923
1081
  var notice = makeNotice(err);
@@ -931,7 +1089,7 @@
931
1089
  // Simulate v8 stack
932
1090
  notice.stack = [notice.message, '\n at ? (', url || 'unknown', ':', line || 0, ':', col || 0, ')'].join('');
933
1091
  }
934
- client.addBreadcrumb((notice.name === 'window.onerror' || !notice.name) ? 'window.onerror' : "window.onerror: " + notice.name, {
1092
+ client.addBreadcrumb((notice.name === 'window.onerror' || !notice.name) ? 'window.onerror' : "window.onerror: ".concat(notice.name), {
935
1093
  category: 'error',
936
1094
  metadata: {
937
1095
  name: notice.name,
@@ -939,7 +1097,9 @@
939
1097
  stack: notice.stack
940
1098
  }
941
1099
  });
942
- client.notify(notice);
1100
+ if (client.config.enableUncaught) {
1101
+ client.notify(notice);
1102
+ }
943
1103
  };
944
1104
  return function (msg, url, line, col, err) {
945
1105
  onerror(msg, url, line, col, err);
@@ -977,14 +1137,14 @@
977
1137
  // const lineNumber = reason.lineNumber || 0
978
1138
  var fileName = 'unknown';
979
1139
  var lineNumber = 0;
980
- var stackFallback = reason.message + "\n at ? (" + fileName + ":" + lineNumber + ")";
1140
+ var stackFallback = "".concat(reason.message, "\n at ? (").concat(fileName, ":").concat(lineNumber, ")");
981
1141
  var stack = reason.stack || stackFallback;
982
1142
  var err = {
983
1143
  name: reason.name,
984
- message: "UnhandledPromiseRejectionWarning: " + reason,
1144
+ message: "UnhandledPromiseRejectionWarning: ".concat(reason),
985
1145
  stack: stack
986
1146
  };
987
- client.addBreadcrumb("window.onunhandledrejection: " + err.name, {
1147
+ client.addBreadcrumb("window.onunhandledrejection: ".concat(err.name), {
988
1148
  category: 'error',
989
1149
  metadata: err
990
1150
  });
@@ -994,7 +1154,7 @@
994
1154
  var message = typeof reason === 'string' ? reason : ((_a = JSON.stringify(reason)) !== null && _a !== void 0 ? _a : 'Unspecified reason');
995
1155
  client.notify({
996
1156
  name: 'window.onunhandledrejection',
997
- message: "UnhandledPromiseRejectionWarning: " + message
1157
+ message: "UnhandledPromiseRejectionWarning: ".concat(message)
998
1158
  });
999
1159
  }
1000
1160
  return function (promiseRejectionEvent) {
@@ -1103,7 +1263,7 @@
1103
1263
  var xhr = this;
1104
1264
  var url = arguments[1];
1105
1265
  var method = typeof arguments[0] === 'string' ? arguments[0].toUpperCase() : arguments[0];
1106
- var message = method + " " + localURLPathname(url);
1266
+ var message = "".concat(method, " ").concat(localURLPathname(url));
1107
1267
  this.__hb_xhr = {
1108
1268
  type: 'xhr',
1109
1269
  method: method,
@@ -1188,7 +1348,7 @@
1188
1348
  if (typeof method === 'string') {
1189
1349
  method = method.toUpperCase();
1190
1350
  }
1191
- var message = method + " " + localURLPathname(url);
1351
+ var message = "".concat(method, " ").concat(localURLPathname(url));
1192
1352
  var metadata = {
1193
1353
  type: 'fetch',
1194
1354
  method: method,
@@ -1301,7 +1461,7 @@
1301
1461
  var prototype = _window[prop] && _window[prop].prototype;
1302
1462
  if (prototype && Object.prototype.hasOwnProperty.call(prototype, 'addEventListener')) {
1303
1463
  instrument(prototype, 'addEventListener', function (original) {
1304
- var wrapOpts = { component: prop + ".prototype.addEventListener" };
1464
+ var wrapOpts = { component: "".concat(prop, ".prototype.addEventListener") };
1305
1465
  // See https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener
1306
1466
  return function (type, listener, useCapture, wantsUntrusted) {
1307
1467
  try {
@@ -1392,10 +1552,6 @@
1392
1552
  var _this = this;
1393
1553
  this.__incrementErrorsCount();
1394
1554
  var payload = this.__buildPayload(notice);
1395
- var handlers = Array.prototype.slice.call(this.__afterNotifyHandlers);
1396
- if (notice.afterNotify) {
1397
- handlers.unshift(notice.afterNotify);
1398
- }
1399
1555
  try {
1400
1556
  var x_1 = new XMLHttpRequest();
1401
1557
  x_1.open('POST', endpoint(this.config, '/v1/notices/js'), this.config.async);
@@ -1405,21 +1561,21 @@
1405
1561
  x_1.send(JSON.stringify(sanitize(payload, this.config.maxObjectDepth)));
1406
1562
  x_1.onload = function () {
1407
1563
  if (x_1.status !== 201) {
1408
- runAfterNotifyHandlers(notice, handlers, new Error("Bad HTTP response: " + x_1.status));
1409
- _this.logger.debug("Unable to send error report: " + x_1.status + ": " + x_1.statusText, x_1, notice);
1564
+ runAfterNotifyHandlers(notice, _this.__afterNotifyHandlers, new Error("Bad HTTP response: ".concat(x_1.status)));
1565
+ _this.logger.debug("Unable to send error report: ".concat(x_1.status, ": ").concat(x_1.statusText), x_1, notice);
1410
1566
  return;
1411
1567
  }
1568
+ var uuid = JSON.parse(x_1.response).id;
1412
1569
  runAfterNotifyHandlers(merge(notice, {
1413
- id: JSON.parse(x_1.response).id
1414
- }), handlers);
1415
- _this.logger.debug('Error report sent', notice);
1570
+ id: uuid
1571
+ }), _this.__afterNotifyHandlers);
1572
+ _this.logger.debug("Error report sent \u26A1 https://app.honeybadger.io/notice/".concat(uuid));
1416
1573
  };
1417
1574
  }
1418
1575
  catch (err) {
1419
- runAfterNotifyHandlers(notice, handlers, err);
1576
+ runAfterNotifyHandlers(notice, this.__afterNotifyHandlers, err);
1420
1577
  this.logger.error('Unable to send error report: error while initializing request', err, notice);
1421
1578
  }
1422
- return true;
1423
1579
  };
1424
1580
  /**
1425
1581
  * wrap always returns the same function so that callbacks can be removed via
@@ -1443,14 +1599,7 @@
1443
1599
  // eslint-disable-next-line @typescript-eslint/no-this-alias
1444
1600
  var client_1 = this;
1445
1601
  func.___hb = function () {
1446
- var onErrorEnabled = client_1.config.enableUncaught;
1447
- // Catch if:
1448
- // 1. We explicitly want to catch (i.e. if the error could be
1449
- // caught before reaching window.onerror)
1450
- // 2. The browser provides less information via the window.onerror
1451
- // handler
1452
- // 3. The window.onerror handler is unavailable
1453
- if (opts.catch || preferCatch || !onErrorEnabled) {
1602
+ if (preferCatch) {
1454
1603
  try {
1455
1604
  // eslint-disable-next-line prefer-rest-params
1456
1605
  return func.apply(this, arguments);
@@ -1461,7 +1610,7 @@
1461
1610
  }
1462
1611
  client_1.__lastWrapErr = err;
1463
1612
  ignoreNextOnError();
1464
- client_1.addBreadcrumb(opts.component ? opts.component + ": " + err.name : err.name, {
1613
+ client_1.addBreadcrumb(opts.component ? "".concat(opts.component, ": ").concat(err.name) : err.name, {
1465
1614
  category: 'error',
1466
1615
  metadata: {
1467
1616
  message: err.message,
@@ -1469,7 +1618,9 @@
1469
1618
  stack: err.stack
1470
1619
  }
1471
1620
  });
1472
- client_1.notify(err);
1621
+ if (client_1.config.enableUncaught) {
1622
+ client_1.notify(err);
1623
+ }
1473
1624
  throw (err);
1474
1625
  }
1475
1626
  }
@@ -1508,5 +1659,5 @@
1508
1659
 
1509
1660
  return browser;
1510
1661
 
1511
- })));
1662
+ }));
1512
1663
  //# sourceMappingURL=honeybadger.js.map