@honeybadger-io/js 4.0.0-beta.0 → 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.
- package/dist/browser/honeybadger.js +78 -40
- 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/core/client.d.ts +14 -2
- package/dist/browser/types/core/store.d.ts +7 -0
- package/dist/browser/types/core/types.d.ts +3 -0
- 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 +1 -0
- package/dist/server/honeybadger.js +150 -127
- package/dist/server/types/core/client.d.ts +14 -2
- package/dist/server/types/core/store.d.ts +7 -0
- package/dist/server/types/core/types.d.ts +3 -0
- package/dist/server/types/server/async_store.d.ts +5 -0
- package/dist/server/types/server.d.ts +1 -0
- package/package.json +4 -3
|
@@ -4,8 +4,8 @@ var https = require('https');
|
|
|
4
4
|
var http = require('http');
|
|
5
5
|
var url = require('url');
|
|
6
6
|
var os = require('os');
|
|
7
|
-
var fs = require('fs');
|
|
8
7
|
var domain = require('domain');
|
|
8
|
+
var fs = require('fs');
|
|
9
9
|
|
|
10
10
|
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
11
11
|
|
|
@@ -13,8 +13,8 @@ var https__default = /*#__PURE__*/_interopDefaultLegacy(https);
|
|
|
13
13
|
var http__default = /*#__PURE__*/_interopDefaultLegacy(http);
|
|
14
14
|
var url__default = /*#__PURE__*/_interopDefaultLegacy(url);
|
|
15
15
|
var os__default = /*#__PURE__*/_interopDefaultLegacy(os);
|
|
16
|
-
var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
|
|
17
16
|
var domain__default = /*#__PURE__*/_interopDefaultLegacy(domain);
|
|
17
|
+
var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
|
|
18
18
|
|
|
19
19
|
/*! *****************************************************************************
|
|
20
20
|
Copyright (c) Microsoft Corporation.
|
|
@@ -56,45 +56,7 @@ var __assign = function() {
|
|
|
56
56
|
return t;
|
|
57
57
|
};
|
|
58
58
|
return __assign.apply(this, arguments);
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
function __awaiter(thisArg, _arguments, P, generator) {
|
|
62
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
63
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
64
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
65
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
66
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
67
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function __generator(thisArg, body) {
|
|
72
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
73
|
-
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
74
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
75
|
-
function step(op) {
|
|
76
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
77
|
-
while (_) try {
|
|
78
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
79
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
80
|
-
switch (op[0]) {
|
|
81
|
-
case 0: case 1: t = op; break;
|
|
82
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
83
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
84
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
85
|
-
default:
|
|
86
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
87
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
88
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
89
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
90
|
-
if (t[2]) _.ops.pop();
|
|
91
|
-
_.trys.pop(); continue;
|
|
92
|
-
}
|
|
93
|
-
op = body.call(thisArg, _);
|
|
94
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
95
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
96
|
-
}
|
|
97
|
-
}
|
|
59
|
+
};
|
|
98
60
|
|
|
99
61
|
var UNKNOWN_FUNCTION = '<unknown>';
|
|
100
62
|
/**
|
|
@@ -307,7 +269,7 @@ function runBeforeNotifyHandlers(notice, handlers) {
|
|
|
307
269
|
}
|
|
308
270
|
function runAfterNotifyHandlers(notice, handlers, error) {
|
|
309
271
|
if (notice && notice.afterNotify) {
|
|
310
|
-
|
|
272
|
+
notice.afterNotify(error, notice);
|
|
311
273
|
}
|
|
312
274
|
for (var i = 0, len = handlers.length; i < len; i++) {
|
|
313
275
|
handlers[i](error, notice);
|
|
@@ -370,7 +332,7 @@ function sanitize(obj, maxDepth) {
|
|
|
370
332
|
}
|
|
371
333
|
// Serialize inside arrays
|
|
372
334
|
if (Array.isArray(obj)) {
|
|
373
|
-
return obj.map(function (o) { return
|
|
335
|
+
return obj.map(function (o) { return safeSerialize(o, depth + 1); });
|
|
374
336
|
}
|
|
375
337
|
// Serialize inside objects
|
|
376
338
|
if (typeof (obj) === 'object') {
|
|
@@ -378,7 +340,7 @@ function sanitize(obj, maxDepth) {
|
|
|
378
340
|
for (var k in obj) {
|
|
379
341
|
var v = obj[k];
|
|
380
342
|
if (Object.prototype.hasOwnProperty.call(obj, k) && (k != null) && (v != null)) {
|
|
381
|
-
ret[k] =
|
|
343
|
+
ret[k] = safeSerialize(v, depth + 1);
|
|
382
344
|
}
|
|
383
345
|
}
|
|
384
346
|
return ret;
|
|
@@ -386,7 +348,16 @@ function sanitize(obj, maxDepth) {
|
|
|
386
348
|
// Return everything else untouched
|
|
387
349
|
return obj;
|
|
388
350
|
}
|
|
389
|
-
|
|
351
|
+
function safeSerialize(obj, depth) {
|
|
352
|
+
if (depth === void 0) { depth = 0; }
|
|
353
|
+
try {
|
|
354
|
+
return serialize(obj, depth);
|
|
355
|
+
}
|
|
356
|
+
catch (e) {
|
|
357
|
+
return "[ERROR] ".concat(e);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
return safeSerialize(obj);
|
|
390
361
|
}
|
|
391
362
|
function logger(client) {
|
|
392
363
|
var log = function (method) {
|
|
@@ -425,7 +396,7 @@ function makeNotice(thing) {
|
|
|
425
396
|
if (!thing) {
|
|
426
397
|
notice = {};
|
|
427
398
|
}
|
|
428
|
-
else if (Object.prototype.toString.call(thing) === '[object Error]') {
|
|
399
|
+
else if (thing instanceof Error || Object.prototype.toString.call(thing) === '[object Error]') {
|
|
429
400
|
var e = thing;
|
|
430
401
|
notice = merge(thing, { name: e.name, message: e.message, stack: e.stack });
|
|
431
402
|
}
|
|
@@ -572,33 +543,44 @@ function getSourceCodeSnippet(fileData, lineNumber, sourceRadius) {
|
|
|
572
543
|
return result;
|
|
573
544
|
}
|
|
574
545
|
|
|
546
|
+
var GlobalStore$1 = /** @class */ (function () {
|
|
547
|
+
function GlobalStore(store) {
|
|
548
|
+
this.store = store;
|
|
549
|
+
}
|
|
550
|
+
GlobalStore.prototype.getStore = function () {
|
|
551
|
+
return this.store;
|
|
552
|
+
};
|
|
553
|
+
GlobalStore.prototype.run = function (store, callback) {
|
|
554
|
+
var args = [];
|
|
555
|
+
for (var _i = 2; _i < arguments.length; _i++) {
|
|
556
|
+
args[_i - 2] = arguments[_i];
|
|
557
|
+
}
|
|
558
|
+
this.store = store;
|
|
559
|
+
return callback.apply(void 0, args);
|
|
560
|
+
};
|
|
561
|
+
return GlobalStore;
|
|
562
|
+
}());
|
|
563
|
+
|
|
575
564
|
var notifier = {
|
|
576
565
|
name: 'honeybadger-js',
|
|
577
566
|
url: 'https://github.com/honeybadger-io/honeybadger-js',
|
|
578
|
-
version: '4.0.0-beta.
|
|
567
|
+
version: '4.0.0-beta.1'
|
|
579
568
|
};
|
|
580
|
-
// Split at commas
|
|
581
|
-
var TAG_SEPARATOR =
|
|
582
|
-
// Removes any non-word characters
|
|
583
|
-
var TAG_SANITIZER = /[^\w]/g;
|
|
584
|
-
// Checks for blank strings
|
|
585
|
-
var STRING_EMPTY = '';
|
|
569
|
+
// Split at commas and spaces
|
|
570
|
+
var TAG_SEPARATOR = /,|\s+/;
|
|
586
571
|
// Checks for non-blank characters
|
|
587
572
|
var NOT_BLANK = /\S/;
|
|
588
573
|
var Client = /** @class */ (function () {
|
|
589
574
|
function Client(opts) {
|
|
590
575
|
if (opts === void 0) { opts = {}; }
|
|
591
|
-
/** @internal */
|
|
592
576
|
this.__pluginsExecuted = false;
|
|
593
|
-
|
|
594
|
-
this.__context = {};
|
|
595
|
-
/** @internal */
|
|
596
|
-
this.__breadcrumbs = [];
|
|
597
|
-
/** @internal */
|
|
577
|
+
this.__store = null;
|
|
598
578
|
this.__beforeNotifyHandlers = [];
|
|
599
|
-
/** @internal */
|
|
600
579
|
this.__afterNotifyHandlers = [];
|
|
601
580
|
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);
|
|
581
|
+
// First, we go with the global (shared) store.
|
|
582
|
+
// Webserver middleware can then switch to the AsyncStore for async context tracking.
|
|
583
|
+
this.__store = new GlobalStore$1({ context: {}, breadcrumbs: [] });
|
|
602
584
|
this.logger = logger(this);
|
|
603
585
|
}
|
|
604
586
|
Client.prototype.factory = function (_opts) {
|
|
@@ -619,6 +601,10 @@ var Client = /** @class */ (function () {
|
|
|
619
601
|
}
|
|
620
602
|
return this;
|
|
621
603
|
};
|
|
604
|
+
/** @internal */
|
|
605
|
+
Client.prototype.__setStore = function (store) {
|
|
606
|
+
this.__store = store;
|
|
607
|
+
};
|
|
622
608
|
Client.prototype.beforeNotify = function (handler) {
|
|
623
609
|
this.__beforeNotifyHandlers.push(handler);
|
|
624
610
|
return this;
|
|
@@ -629,23 +615,26 @@ var Client = /** @class */ (function () {
|
|
|
629
615
|
};
|
|
630
616
|
Client.prototype.setContext = function (context) {
|
|
631
617
|
if (typeof context === 'object') {
|
|
632
|
-
|
|
618
|
+
var store = this.__store.getStore();
|
|
619
|
+
store.context = merge(store.context, context);
|
|
633
620
|
}
|
|
634
621
|
return this;
|
|
635
622
|
};
|
|
636
623
|
Client.prototype.resetContext = function (context) {
|
|
637
624
|
this.logger.warn('Deprecation warning: `Honeybadger.resetContext()` has been deprecated; please use `Honeybadger.clear()` instead.');
|
|
625
|
+
var store = this.__store.getStore();
|
|
638
626
|
if (typeof context === 'object' && context !== null) {
|
|
639
|
-
|
|
627
|
+
store.context = context;
|
|
640
628
|
}
|
|
641
629
|
else {
|
|
642
|
-
|
|
630
|
+
store.context = {};
|
|
643
631
|
}
|
|
644
632
|
return this;
|
|
645
633
|
};
|
|
646
634
|
Client.prototype.clear = function () {
|
|
647
|
-
|
|
648
|
-
|
|
635
|
+
var store = this.__store.getStore();
|
|
636
|
+
store.context = {};
|
|
637
|
+
store.breadcrumbs = [];
|
|
649
638
|
return this;
|
|
650
639
|
};
|
|
651
640
|
Client.prototype.notify = function (noticeable, name, extra) {
|
|
@@ -687,10 +676,11 @@ var Client = /** @class */ (function () {
|
|
|
687
676
|
stack: notice.stack
|
|
688
677
|
}
|
|
689
678
|
});
|
|
690
|
-
|
|
679
|
+
var breadcrumbs = this.__getStoreOrDefaultObject().breadcrumbs;
|
|
680
|
+
notice.__breadcrumbs = this.config.breadcrumbsEnabled ? breadcrumbs.slice() : [];
|
|
691
681
|
// we need to have the source file data before the beforeNotifyHandlers,
|
|
692
682
|
// in case they modify them
|
|
693
|
-
var sourceCodeData = notice ? notice.backtrace.
|
|
683
|
+
var sourceCodeData = notice && notice.backtrace ? notice.backtrace.map(function (trace) { return newObject(trace); }) : null;
|
|
694
684
|
getSourceForBacktrace(sourceCodeData, this.__getSourceFileHandler, function (sourcePerTrace) {
|
|
695
685
|
sourcePerTrace.forEach(function (source, index) {
|
|
696
686
|
notice.backtrace[index].source = source;
|
|
@@ -761,15 +751,16 @@ var Client = /** @class */ (function () {
|
|
|
761
751
|
if (objectIsEmpty(notice)) {
|
|
762
752
|
return null;
|
|
763
753
|
}
|
|
754
|
+
var context = this.__getStoreOrDefaultObject().context;
|
|
764
755
|
var noticeTags = this.__constructTags(notice.tags);
|
|
765
|
-
var contextTags = this.__constructTags(
|
|
756
|
+
var contextTags = this.__constructTags(context["tags"]);
|
|
766
757
|
var configTags = this.__constructTags(this.config.tags);
|
|
767
758
|
// Turning into a Set will remove duplicates
|
|
768
759
|
var tags = noticeTags.concat(contextTags).concat(configTags);
|
|
769
760
|
var uniqueTags = tags.filter(function (item, index) { return tags.indexOf(item) === index; });
|
|
770
761
|
notice = merge(notice, {
|
|
771
762
|
name: notice.name || 'Error',
|
|
772
|
-
context: merge(
|
|
763
|
+
context: merge(context, notice.context),
|
|
773
764
|
projectRoot: notice.projectRoot || this.config.projectRoot,
|
|
774
765
|
environment: notice.environment || this.config.environment,
|
|
775
766
|
component: notice.component || this.config.component,
|
|
@@ -793,30 +784,30 @@ var Client = /** @class */ (function () {
|
|
|
793
784
|
var metadata = newObject(opts.metadata);
|
|
794
785
|
var category = opts.category || 'custom';
|
|
795
786
|
var timestamp = new Date().toISOString();
|
|
796
|
-
this.
|
|
787
|
+
var store = this.__store.getStore();
|
|
788
|
+
var breadcrumbs = store.breadcrumbs;
|
|
789
|
+
breadcrumbs.push({
|
|
797
790
|
category: category,
|
|
798
791
|
message: message,
|
|
799
792
|
metadata: metadata,
|
|
800
793
|
timestamp: timestamp
|
|
801
794
|
});
|
|
802
795
|
var limit = this.config.maxBreadcrumbs;
|
|
803
|
-
if (
|
|
804
|
-
|
|
796
|
+
if (breadcrumbs.length > limit) {
|
|
797
|
+
breadcrumbs = breadcrumbs.slice(breadcrumbs.length - limit);
|
|
805
798
|
}
|
|
799
|
+
store.breadcrumbs = breadcrumbs;
|
|
806
800
|
return this;
|
|
807
801
|
};
|
|
808
|
-
/** @internal */
|
|
809
802
|
Client.prototype.__developmentMode = function () {
|
|
810
803
|
if (this.config.reportData === true) {
|
|
811
804
|
return false;
|
|
812
805
|
}
|
|
813
806
|
return (this.config.environment && this.config.developmentEnvironments.includes(this.config.environment));
|
|
814
807
|
};
|
|
815
|
-
/** @internal */
|
|
816
808
|
Client.prototype.__send = function (_notice) {
|
|
817
809
|
throw (new Error('Must implement send in subclass'));
|
|
818
810
|
};
|
|
819
|
-
/** @internal */
|
|
820
811
|
Client.prototype.__buildPayload = function (notice) {
|
|
821
812
|
var headers = filter(notice.headers, this.config.filters) || {};
|
|
822
813
|
var cgiData = filter(__assign(__assign({}, notice.cgiData), formatCGIData(headers, 'HTTP_')), this.config.filters);
|
|
@@ -852,14 +843,22 @@ var Client = /** @class */ (function () {
|
|
|
852
843
|
details: notice.details || {}
|
|
853
844
|
};
|
|
854
845
|
};
|
|
855
|
-
/** @internal */
|
|
856
846
|
Client.prototype.__constructTags = function (tags) {
|
|
857
847
|
if (!tags) {
|
|
858
848
|
return [];
|
|
859
849
|
}
|
|
860
|
-
return tags.toString().split(TAG_SEPARATOR).
|
|
861
|
-
|
|
862
|
-
|
|
850
|
+
return tags.toString().split(TAG_SEPARATOR).filter(function (tag) { return NOT_BLANK.test(tag); });
|
|
851
|
+
};
|
|
852
|
+
/**
|
|
853
|
+
* For ALS, the store may be uninitialized (if .run()` has not been called).
|
|
854
|
+
* This provides an easy way to read the existing store object or fall back to a default.
|
|
855
|
+
* Returns *a copy* of the store.
|
|
856
|
+
* @internal
|
|
857
|
+
*/
|
|
858
|
+
Client.prototype.__getStoreOrDefaultObject = function () {
|
|
859
|
+
var existingStore = this.__store.getStore();
|
|
860
|
+
var store = existingStore || {};
|
|
861
|
+
return __assign({ context: {}, breadcrumbs: [] }, store);
|
|
863
862
|
};
|
|
864
863
|
return Client;
|
|
865
864
|
}());
|
|
@@ -920,55 +919,63 @@ function getSourceFile(path, cb) {
|
|
|
920
919
|
});
|
|
921
920
|
}
|
|
922
921
|
|
|
922
|
+
var Store;
|
|
923
|
+
try {
|
|
924
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
925
|
+
var AsyncLocalStorage = require('async_hooks').AsyncLocalStorage;
|
|
926
|
+
Store = new AsyncLocalStorage();
|
|
927
|
+
}
|
|
928
|
+
catch (e) {
|
|
929
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
930
|
+
var GlobalStore = require('../core/store').GlobalStore;
|
|
931
|
+
Store = new GlobalStore();
|
|
932
|
+
}
|
|
933
|
+
var AsyncStore = Store;
|
|
934
|
+
|
|
923
935
|
function isHandlerSync(handler) {
|
|
924
936
|
return handler.length > 2;
|
|
925
937
|
}
|
|
926
|
-
function
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
_a.trys.push([0, 2, , 3]);
|
|
934
|
-
return [4 /*yield*/, handler(event, context)];
|
|
935
|
-
case 1: return [2 /*return*/, _a.sent()];
|
|
936
|
-
case 2:
|
|
937
|
-
err_1 = _a.sent();
|
|
938
|
-
return [2 /*return*/, new Promise(function (_, reject) {
|
|
939
|
-
hb.notify(err_1, {
|
|
940
|
-
afterNotify: function () {
|
|
941
|
-
hb.clear();
|
|
942
|
-
reject(err_1);
|
|
943
|
-
}
|
|
944
|
-
});
|
|
945
|
-
})];
|
|
946
|
-
case 3: return [2 /*return*/];
|
|
947
|
-
}
|
|
948
|
-
});
|
|
949
|
-
}); };
|
|
938
|
+
function reportToHoneybadger(hb, err, callback) {
|
|
939
|
+
hb.notify(err, {
|
|
940
|
+
afterNotify: function () {
|
|
941
|
+
hb.clear();
|
|
942
|
+
callback(err);
|
|
943
|
+
}
|
|
944
|
+
});
|
|
950
945
|
}
|
|
951
|
-
function
|
|
952
|
-
return function (event, context
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
946
|
+
function asyncHandler(handler, hb) {
|
|
947
|
+
return function wrappedLambdaHandler(event, context) {
|
|
948
|
+
hb.__setStore(AsyncStore);
|
|
949
|
+
return new Promise(function (resolve, reject) {
|
|
950
|
+
AsyncStore.run({ context: {}, breadcrumbs: [] }, function () {
|
|
951
|
+
try {
|
|
952
|
+
handler(event, context)
|
|
953
|
+
.then(resolve)
|
|
954
|
+
.catch(function (err) { return reportToHoneybadger(hb, err, reject); });
|
|
958
955
|
}
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
try {
|
|
962
|
-
handler(event, context, function (error, result) {
|
|
963
|
-
if (error) {
|
|
964
|
-
return hbHandler(error);
|
|
956
|
+
catch (err) {
|
|
957
|
+
reportToHoneybadger(hb, err, reject);
|
|
965
958
|
}
|
|
966
|
-
cb(null, result);
|
|
967
959
|
});
|
|
968
|
-
}
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
960
|
+
});
|
|
961
|
+
};
|
|
962
|
+
}
|
|
963
|
+
function syncHandler(handler, hb) {
|
|
964
|
+
return function wrappedLambdaHandler(event, context, cb) {
|
|
965
|
+
hb.__setStore(AsyncStore);
|
|
966
|
+
AsyncStore.run({ context: {}, breadcrumbs: [] }, function () {
|
|
967
|
+
try {
|
|
968
|
+
handler(event, context, function (error, result) {
|
|
969
|
+
if (error) {
|
|
970
|
+
return reportToHoneybadger(hb, error, cb);
|
|
971
|
+
}
|
|
972
|
+
cb(null, result);
|
|
973
|
+
});
|
|
974
|
+
}
|
|
975
|
+
catch (err) {
|
|
976
|
+
reportToHoneybadger(hb, err, cb);
|
|
977
|
+
}
|
|
978
|
+
});
|
|
972
979
|
};
|
|
973
980
|
}
|
|
974
981
|
function lambdaHandler(handler) {
|
|
@@ -1065,10 +1072,7 @@ function fullUrl(req) {
|
|
|
1065
1072
|
});
|
|
1066
1073
|
}
|
|
1067
1074
|
function requestHandler(req, res, next) {
|
|
1068
|
-
this.
|
|
1069
|
-
var dom = domain__default["default"].create();
|
|
1070
|
-
dom.on('error', next);
|
|
1071
|
-
dom.run(next);
|
|
1075
|
+
this.run(next, next);
|
|
1072
1076
|
}
|
|
1073
1077
|
function errorHandler(err, req, _res, next) {
|
|
1074
1078
|
this.notify(err, {
|
|
@@ -1144,7 +1148,7 @@ var Honeybadger = /** @class */ (function (_super) {
|
|
|
1144
1148
|
runAfterNotifyHandlers(merge(notice, {
|
|
1145
1149
|
id: uuid
|
|
1146
1150
|
}), _this.__afterNotifyHandlers);
|
|
1147
|
-
_this.logger.info(
|
|
1151
|
+
_this.logger.info("Error report sent \u26A1 https://app.honeybadger.io/notice/".concat(uuid));
|
|
1148
1152
|
});
|
|
1149
1153
|
});
|
|
1150
1154
|
req.on('error', function (err) {
|
|
@@ -1155,13 +1159,32 @@ var Honeybadger = /** @class */ (function (_super) {
|
|
|
1155
1159
|
req.end();
|
|
1156
1160
|
});
|
|
1157
1161
|
};
|
|
1162
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1163
|
+
Honeybadger.prototype.run = function (handler, onError) {
|
|
1164
|
+
var _this = this;
|
|
1165
|
+
var storeObject = this.__getStoreOrDefaultObject();
|
|
1166
|
+
this.__setStore(AsyncStore);
|
|
1167
|
+
if (onError) {
|
|
1168
|
+
// ALS is fine for context-tracking, but `domain` allows us to catch errors
|
|
1169
|
+
// thrown asynchronously (timers, event emitters)
|
|
1170
|
+
// We can't use unhandledRejection/uncaughtException listeners; they're global and shared across all requests
|
|
1171
|
+
// But the `onError` handler might be request-specific.
|
|
1172
|
+
// Note that this doesn't still handle all cases. `domain` has its own problems:
|
|
1173
|
+
// See https://github.com/honeybadger-io/honeybadger-js/pull/711
|
|
1174
|
+
var dom = domain__default["default"].create();
|
|
1175
|
+
var onErrorWithContext = function (err) { return _this.__store.run(storeObject, function () { return onError(err); }); };
|
|
1176
|
+
dom.on('error', onErrorWithContext);
|
|
1177
|
+
handler = dom.bind(handler);
|
|
1178
|
+
}
|
|
1179
|
+
return this.__store.run(storeObject, handler);
|
|
1180
|
+
};
|
|
1158
1181
|
return Honeybadger;
|
|
1159
1182
|
}(Client));
|
|
1160
1183
|
var server = new Honeybadger({
|
|
1161
1184
|
__plugins: [
|
|
1162
1185
|
uncaughtException(),
|
|
1163
1186
|
unhandledRejection()
|
|
1164
|
-
]
|
|
1187
|
+
],
|
|
1165
1188
|
});
|
|
1166
1189
|
|
|
1167
1190
|
module.exports = server;
|
|
@@ -1,9 +1,17 @@
|
|
|
1
|
-
import { Config, Logger, BeforeNotifyHandler, AfterNotifyHandler, Notice, Noticeable } from './types';
|
|
1
|
+
import { Config, Logger, BeforeNotifyHandler, AfterNotifyHandler, Notice, Noticeable, HoneybadgerStore, BreadcrumbRecord } from './types';
|
|
2
2
|
export default class Client {
|
|
3
|
+
private __pluginsExecuted;
|
|
4
|
+
protected __store: HoneybadgerStore<{
|
|
5
|
+
context: Record<string, unknown>;
|
|
6
|
+
breadcrumbs: BreadcrumbRecord[];
|
|
7
|
+
}>;
|
|
8
|
+
protected __beforeNotifyHandlers: BeforeNotifyHandler[];
|
|
9
|
+
protected __afterNotifyHandlers: AfterNotifyHandler[];
|
|
10
|
+
protected __getSourceFileHandler: (path: string, cb: (fileContent: string) => void) => void;
|
|
3
11
|
config: Config;
|
|
4
12
|
logger: Logger;
|
|
5
13
|
constructor(opts?: Partial<Config>);
|
|
6
|
-
factory(_opts?:
|
|
14
|
+
factory(_opts?: Partial<Config>): Client;
|
|
7
15
|
getVersion(): string;
|
|
8
16
|
configure(opts?: Partial<Config>): Client;
|
|
9
17
|
beforeNotify(handler: BeforeNotifyHandler): Client;
|
|
@@ -21,4 +29,8 @@ export default class Client {
|
|
|
21
29
|
notifyAsync(noticeable: Noticeable, name?: string | Partial<Notice>, extra?: Partial<Notice>): Promise<void>;
|
|
22
30
|
protected makeNotice(noticeable: Noticeable, name?: string | Partial<Notice>, extra?: Partial<Notice>): Notice | null;
|
|
23
31
|
addBreadcrumb(message: string, opts?: Record<string, unknown>): Client;
|
|
32
|
+
protected __developmentMode(): boolean;
|
|
33
|
+
protected __send(_notice: Partial<Notice>): void;
|
|
34
|
+
protected __buildPayload(notice: Notice): Record<string, Record<string, unknown>>;
|
|
35
|
+
protected __constructTags(tags: unknown): Array<string>;
|
|
24
36
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { HoneybadgerStore } from "./types";
|
|
2
|
+
export declare class GlobalStore<T> implements HoneybadgerStore<T> {
|
|
3
|
+
private store;
|
|
4
|
+
constructor(store: T);
|
|
5
|
+
getStore(): T;
|
|
6
|
+
run<R, TArgs extends never[]>(store: T, callback: (...args: TArgs) => R, ...args: TArgs): R;
|
|
7
|
+
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
import Client from './client';
|
|
3
|
+
import { AsyncLocalStorage } from "async_hooks";
|
|
2
4
|
export interface Logger {
|
|
3
5
|
log(...args: unknown[]): unknown;
|
|
4
6
|
info(...args: unknown[]): unknown;
|
|
@@ -88,3 +90,4 @@ export interface CGIData {
|
|
|
88
90
|
HTTP_COOKIE: string | undefined;
|
|
89
91
|
[x: string]: unknown;
|
|
90
92
|
}
|
|
93
|
+
export declare type HoneybadgerStore<T> = Pick<AsyncLocalStorage<T>, 'getStore' | 'run'>;
|
|
@@ -8,6 +8,7 @@ declare class Honeybadger extends Client {
|
|
|
8
8
|
lambdaHandler: typeof lambdaHandler;
|
|
9
9
|
constructor(opts?: Partial<Config>);
|
|
10
10
|
factory(opts?: Partial<Config>): Honeybadger;
|
|
11
|
+
run<R>(handler: (...args: never[]) => R, onError?: (...args: any[]) => any): R | void;
|
|
11
12
|
}
|
|
12
13
|
declare const _default: Honeybadger;
|
|
13
14
|
export default _default;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@honeybadger-io/js",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"homepage": "https://github.com/honeybadger-io/honeybadger-js",
|
|
6
6
|
"author": {
|
|
@@ -46,11 +46,12 @@
|
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@rollup/plugin-node-resolve": "^13.0.6",
|
|
49
|
-
"@rollup/plugin-replace": "^
|
|
49
|
+
"@rollup/plugin-replace": "^4.0.0",
|
|
50
50
|
"@rollup/plugin-typescript": "^8.3.0",
|
|
51
51
|
"@types/aws-lambda": "^8.10.89",
|
|
52
52
|
"@types/express": "^4.17.13",
|
|
53
53
|
"@types/jest": "^27.0.3",
|
|
54
|
+
"@types/node": "^12.20.46",
|
|
54
55
|
"@typescript-eslint/eslint-plugin": "^5.6.0",
|
|
55
56
|
"@typescript-eslint/parser": "^5.6.0",
|
|
56
57
|
"axios": ">=0.24.0",
|
|
@@ -64,7 +65,7 @@
|
|
|
64
65
|
"nock": "^13.2.1",
|
|
65
66
|
"rollup": "^2.61.1",
|
|
66
67
|
"rollup-plugin-uglify": "^6.0.2",
|
|
67
|
-
"shipjs": "0.24.
|
|
68
|
+
"shipjs": "0.24.3",
|
|
68
69
|
"sinon": "^13.0.1",
|
|
69
70
|
"supertest": "^6.1.6",
|
|
70
71
|
"ts-jest": "^27.1.1",
|