@honeybadger-io/js 6.15.2 → 6.16.0
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.ext.min.js +1 -1
- package/dist/browser/honeybadger.ext.min.js.map +1 -1
- package/dist/browser/honeybadger.js +355 -58
- 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/server/async_store.d.ts +2 -0
- package/dist/server/fastify.d.ts +31 -0
- package/dist/server/fastify.js +2149 -0
- package/dist/server/fastify.js.map +1 -0
- package/dist/server/honeybadger.js +707 -81
- package/dist/server/honeybadger.js.map +1 -1
- package/dist/server/instrumentation/http_event.d.ts +51 -0
- package/dist/server/integrations/shutdown_monitor.d.ts +2 -0
- package/dist/server/stacked_store.d.ts +2 -0
- package/package.json +19 -3
|
@@ -0,0 +1,2149 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var require$$0$2 = require('crypto');
|
|
6
|
+
|
|
7
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
8
|
+
|
|
9
|
+
var require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0$2);
|
|
10
|
+
|
|
11
|
+
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
12
|
+
|
|
13
|
+
function getAugmentedNamespace(n) {
|
|
14
|
+
var f = n.default;
|
|
15
|
+
if (typeof f == "function") {
|
|
16
|
+
var a = function () {
|
|
17
|
+
return f.apply(this, arguments);
|
|
18
|
+
};
|
|
19
|
+
a.prototype = f.prototype;
|
|
20
|
+
} else a = {};
|
|
21
|
+
Object.defineProperty(a, '__esModule', {value: true});
|
|
22
|
+
Object.keys(n).forEach(function (k) {
|
|
23
|
+
var d = Object.getOwnPropertyDescriptor(n, k);
|
|
24
|
+
Object.defineProperty(a, k, d.get ? d : {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
get: function () {
|
|
27
|
+
return n[k];
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
return a;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
var fastify = {};
|
|
35
|
+
|
|
36
|
+
var src = {};
|
|
37
|
+
|
|
38
|
+
var console_events = {};
|
|
39
|
+
|
|
40
|
+
var util = {};
|
|
41
|
+
|
|
42
|
+
var UNKNOWN_FUNCTION = '<unknown>';
|
|
43
|
+
/**
|
|
44
|
+
* This parses the different stack traces and puts them into one format
|
|
45
|
+
* This borrows heavily from TraceKit (https://github.com/csnover/TraceKit)
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
function parse(stackString) {
|
|
49
|
+
var lines = stackString.split('\n');
|
|
50
|
+
return lines.reduce(function (stack, line) {
|
|
51
|
+
var parseResult = parseChrome(line) || parseWinjs(line) || parseGecko(line) || parseNode(line) || parseJSC(line);
|
|
52
|
+
|
|
53
|
+
if (parseResult) {
|
|
54
|
+
stack.push(parseResult);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return stack;
|
|
58
|
+
}, []);
|
|
59
|
+
}
|
|
60
|
+
var chromeRe = /^\s*at (.*?) ?\(((?:file|https?|blob|chrome-extension|native|eval|webpack|rsc|<anonymous>|\/|[a-z]:\\|\\\\).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
|
|
61
|
+
var chromeEvalRe = /\((\S*)(?::(\d+))(?::(\d+))\)/;
|
|
62
|
+
|
|
63
|
+
function parseChrome(line) {
|
|
64
|
+
var parts = chromeRe.exec(line);
|
|
65
|
+
|
|
66
|
+
if (!parts) {
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
var isNative = parts[2] && parts[2].indexOf('native') === 0; // start of line
|
|
71
|
+
|
|
72
|
+
var isEval = parts[2] && parts[2].indexOf('eval') === 0; // start of line
|
|
73
|
+
|
|
74
|
+
var submatch = chromeEvalRe.exec(parts[2]);
|
|
75
|
+
|
|
76
|
+
if (isEval && submatch != null) {
|
|
77
|
+
// throw out eval line/column and use top-most line/column number
|
|
78
|
+
parts[2] = submatch[1]; // url
|
|
79
|
+
|
|
80
|
+
parts[3] = submatch[2]; // line
|
|
81
|
+
|
|
82
|
+
parts[4] = submatch[3]; // column
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
file: !isNative ? parts[2] : null,
|
|
87
|
+
methodName: parts[1] || UNKNOWN_FUNCTION,
|
|
88
|
+
arguments: isNative ? [parts[2]] : [],
|
|
89
|
+
lineNumber: parts[3] ? +parts[3] : null,
|
|
90
|
+
column: parts[4] ? +parts[4] : null
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
var winjsRe = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx|https?|webpack|rsc|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i;
|
|
95
|
+
|
|
96
|
+
function parseWinjs(line) {
|
|
97
|
+
var parts = winjsRe.exec(line);
|
|
98
|
+
|
|
99
|
+
if (!parts) {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
file: parts[2],
|
|
105
|
+
methodName: parts[1] || UNKNOWN_FUNCTION,
|
|
106
|
+
arguments: [],
|
|
107
|
+
lineNumber: +parts[3],
|
|
108
|
+
column: parts[4] ? +parts[4] : null
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
var geckoRe = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)((?:file|https?|blob|chrome|webpack|rsc|resource|\[native).*?|[^@]*bundle)(?::(\d+))?(?::(\d+))?\s*$/i;
|
|
113
|
+
var geckoEvalRe = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i;
|
|
114
|
+
|
|
115
|
+
function parseGecko(line) {
|
|
116
|
+
var parts = geckoRe.exec(line);
|
|
117
|
+
|
|
118
|
+
if (!parts) {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
var isEval = parts[3] && parts[3].indexOf(' > eval') > -1;
|
|
123
|
+
var submatch = geckoEvalRe.exec(parts[3]);
|
|
124
|
+
|
|
125
|
+
if (isEval && submatch != null) {
|
|
126
|
+
// throw out eval line/column and use top-most line number
|
|
127
|
+
parts[3] = submatch[1];
|
|
128
|
+
parts[4] = submatch[2];
|
|
129
|
+
parts[5] = null; // no column when eval
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return {
|
|
133
|
+
file: parts[3],
|
|
134
|
+
methodName: parts[1] || UNKNOWN_FUNCTION,
|
|
135
|
+
arguments: parts[2] ? parts[2].split(',') : [],
|
|
136
|
+
lineNumber: parts[4] ? +parts[4] : null,
|
|
137
|
+
column: parts[5] ? +parts[5] : null
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
var javaScriptCoreRe = /^\s*(?:([^@]*)(?:\((.*?)\))?@)?(\S.*?):(\d+)(?::(\d+))?\s*$/i;
|
|
142
|
+
|
|
143
|
+
function parseJSC(line) {
|
|
144
|
+
var parts = javaScriptCoreRe.exec(line);
|
|
145
|
+
|
|
146
|
+
if (!parts) {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return {
|
|
151
|
+
file: parts[3],
|
|
152
|
+
methodName: parts[1] || UNKNOWN_FUNCTION,
|
|
153
|
+
arguments: [],
|
|
154
|
+
lineNumber: +parts[4],
|
|
155
|
+
column: parts[5] ? +parts[5] : null
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
var nodeRe = /^\s*at (?:((?:\[object object\])?[^\\/]+(?: \[as \S+\])?) )?\(?(.*?):(\d+)(?::(\d+))?\)?\s*$/i;
|
|
160
|
+
|
|
161
|
+
function parseNode(line) {
|
|
162
|
+
var parts = nodeRe.exec(line);
|
|
163
|
+
|
|
164
|
+
if (!parts) {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
return {
|
|
169
|
+
file: parts[2],
|
|
170
|
+
methodName: parts[1] || UNKNOWN_FUNCTION,
|
|
171
|
+
arguments: [],
|
|
172
|
+
lineNumber: +parts[3],
|
|
173
|
+
column: parts[4] ? +parts[4] : null
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
var stackTraceParser_esm = /*#__PURE__*/Object.freeze({
|
|
178
|
+
__proto__: null,
|
|
179
|
+
parse: parse
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
var require$$0$1 = /*@__PURE__*/getAugmentedNamespace(stackTraceParser_esm);
|
|
183
|
+
|
|
184
|
+
(function (exports) {
|
|
185
|
+
var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
186
|
+
if (k2 === undefined) k2 = k;
|
|
187
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
188
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
189
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
190
|
+
}
|
|
191
|
+
Object.defineProperty(o, k2, desc);
|
|
192
|
+
}) : (function(o, m, k, k2) {
|
|
193
|
+
if (k2 === undefined) k2 = k;
|
|
194
|
+
o[k2] = m[k];
|
|
195
|
+
}));
|
|
196
|
+
var __setModuleDefault = (commonjsGlobal && commonjsGlobal.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
197
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
198
|
+
}) : function(o, v) {
|
|
199
|
+
o["default"] = v;
|
|
200
|
+
});
|
|
201
|
+
var __importStar = (commonjsGlobal && commonjsGlobal.__importStar) || function (mod) {
|
|
202
|
+
if (mod && mod.__esModule) return mod;
|
|
203
|
+
var result = {};
|
|
204
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
205
|
+
__setModuleDefault(result, mod);
|
|
206
|
+
return result;
|
|
207
|
+
};
|
|
208
|
+
var __awaiter = (commonjsGlobal && commonjsGlobal.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
209
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
210
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
211
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
212
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
213
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
214
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
215
|
+
});
|
|
216
|
+
};
|
|
217
|
+
var __generator = (commonjsGlobal && commonjsGlobal.__generator) || function (thisArg, body) {
|
|
218
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
219
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
220
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
221
|
+
function step(op) {
|
|
222
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
223
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
224
|
+
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;
|
|
225
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
226
|
+
switch (op[0]) {
|
|
227
|
+
case 0: case 1: t = op; break;
|
|
228
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
229
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
230
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
231
|
+
default:
|
|
232
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
233
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
234
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
235
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
236
|
+
if (t[2]) _.ops.pop();
|
|
237
|
+
_.trys.pop(); continue;
|
|
238
|
+
}
|
|
239
|
+
op = body.call(thisArg, _);
|
|
240
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
241
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
242
|
+
}
|
|
243
|
+
};
|
|
244
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
245
|
+
exports.logDeprecatedMethod = exports.globalThisOrWindow = exports.isBrowserConfig = exports.clone = exports.formatCGIData = exports.filterUrl = exports.filter = exports.generateStackTrace = exports.endpoint = exports.instrumentConsole = exports.instrument = exports.isErrorObject = exports.makeNotice = exports.logger = exports.sanitize = exports.shallowClone = exports.runAfterNotifyHandlers = exports.shouldSampleEvent = exports.resolveInsights = exports.runBeforeEventHandlers = exports.runBeforeNotifyHandlers = exports.getSourceForBacktrace = exports.getCauses = exports.calculateBacktraceShift = exports.DEFAULT_BACKTRACE_SHIFT = exports.makeBacktrace = exports.objectIsExtensible = exports.objectIsEmpty = exports.mergeNotice = exports.merge = void 0;
|
|
246
|
+
/* eslint-disable prefer-rest-params */
|
|
247
|
+
var stackTraceParser = __importStar(require$$0$1);
|
|
248
|
+
function merge(obj1, obj2) {
|
|
249
|
+
var result = {};
|
|
250
|
+
for (var k in obj1) {
|
|
251
|
+
result[k] = obj1[k];
|
|
252
|
+
}
|
|
253
|
+
for (var k in obj2) {
|
|
254
|
+
result[k] = obj2[k];
|
|
255
|
+
}
|
|
256
|
+
return result;
|
|
257
|
+
}
|
|
258
|
+
exports.merge = merge;
|
|
259
|
+
function mergeNotice(notice1, notice2) {
|
|
260
|
+
var result = merge(notice1, notice2);
|
|
261
|
+
if (notice1.context && notice2.context) {
|
|
262
|
+
result.context = merge(notice1.context, notice2.context);
|
|
263
|
+
}
|
|
264
|
+
return result;
|
|
265
|
+
}
|
|
266
|
+
exports.mergeNotice = mergeNotice;
|
|
267
|
+
function objectIsEmpty(obj) {
|
|
268
|
+
for (var k in obj) {
|
|
269
|
+
if (Object.prototype.hasOwnProperty.call(obj, k)) {
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return true;
|
|
274
|
+
}
|
|
275
|
+
exports.objectIsEmpty = objectIsEmpty;
|
|
276
|
+
function objectIsExtensible(obj) {
|
|
277
|
+
if (typeof Object.isExtensible !== 'function') {
|
|
278
|
+
return true;
|
|
279
|
+
}
|
|
280
|
+
return Object.isExtensible(obj);
|
|
281
|
+
}
|
|
282
|
+
exports.objectIsExtensible = objectIsExtensible;
|
|
283
|
+
function makeBacktrace(stack, filterHbSourceCode, logger) {
|
|
284
|
+
if (filterHbSourceCode === void 0) { filterHbSourceCode = false; }
|
|
285
|
+
if (logger === void 0) { logger = console; }
|
|
286
|
+
if (!stack) {
|
|
287
|
+
return [];
|
|
288
|
+
}
|
|
289
|
+
try {
|
|
290
|
+
var backtrace = stackTraceParser
|
|
291
|
+
.parse(stack)
|
|
292
|
+
.map(function (line) {
|
|
293
|
+
return {
|
|
294
|
+
file: line.file,
|
|
295
|
+
method: line.methodName,
|
|
296
|
+
number: line.lineNumber,
|
|
297
|
+
column: line.column
|
|
298
|
+
};
|
|
299
|
+
});
|
|
300
|
+
if (filterHbSourceCode) {
|
|
301
|
+
backtrace.splice(0, calculateBacktraceShift(backtrace));
|
|
302
|
+
}
|
|
303
|
+
return backtrace;
|
|
304
|
+
}
|
|
305
|
+
catch (err) {
|
|
306
|
+
logger.debug(err);
|
|
307
|
+
return [];
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
exports.makeBacktrace = makeBacktrace;
|
|
311
|
+
function isFrameFromHbSourceCode(frame) {
|
|
312
|
+
var hasHbFile = false;
|
|
313
|
+
var hasHbMethod = false;
|
|
314
|
+
if (frame.file) {
|
|
315
|
+
hasHbFile = frame.file.toLowerCase().indexOf('@honeybadger-io') > -1;
|
|
316
|
+
}
|
|
317
|
+
if (frame.method) {
|
|
318
|
+
hasHbMethod = frame.method.toLowerCase().indexOf('@honeybadger-io') > -1;
|
|
319
|
+
}
|
|
320
|
+
return hasHbFile || hasHbMethod;
|
|
321
|
+
}
|
|
322
|
+
exports.DEFAULT_BACKTRACE_SHIFT = 3;
|
|
323
|
+
/**
|
|
324
|
+
* If {@link generateStackTrace} is used, we want to exclude frames that come from
|
|
325
|
+
* Honeybadger's source code.
|
|
326
|
+
*
|
|
327
|
+
* Logic:
|
|
328
|
+
* - For each frame, increment the shift if source code is from Honeybadger
|
|
329
|
+
* - If a frame from an <anonymous> file is encountered increment the shift ONLY if between Honeybadger source code
|
|
330
|
+
* (i.e. previous and next frames are from Honeybadger)
|
|
331
|
+
* - Exit when frame encountered is not from Honeybadger source code
|
|
332
|
+
*
|
|
333
|
+
* Note: this will not always work, especially in browser versions where code
|
|
334
|
+
* is minified, uglified and bundled.
|
|
335
|
+
* For those cases we default to 3:
|
|
336
|
+
* - generateStackTrace
|
|
337
|
+
* - makeNotice
|
|
338
|
+
* - notify
|
|
339
|
+
*/
|
|
340
|
+
function calculateBacktraceShift(backtrace) {
|
|
341
|
+
var shift = 0;
|
|
342
|
+
for (var i = 0; i < backtrace.length; i++) {
|
|
343
|
+
var frame = backtrace[i];
|
|
344
|
+
if (isFrameFromHbSourceCode(frame)) {
|
|
345
|
+
shift++;
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
if (!frame.file || frame.file === '<anonymous>') {
|
|
349
|
+
var nextFrame = backtrace[i + 1];
|
|
350
|
+
if (nextFrame && isFrameFromHbSourceCode(nextFrame)) {
|
|
351
|
+
shift++;
|
|
352
|
+
continue;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
break;
|
|
356
|
+
}
|
|
357
|
+
return shift || exports.DEFAULT_BACKTRACE_SHIFT;
|
|
358
|
+
}
|
|
359
|
+
exports.calculateBacktraceShift = calculateBacktraceShift;
|
|
360
|
+
function getCauses(notice, logger) {
|
|
361
|
+
if (notice.cause) {
|
|
362
|
+
var causes = [];
|
|
363
|
+
var cause = notice;
|
|
364
|
+
// @ts-ignore this throws an error if tsconfig.json has strict: true
|
|
365
|
+
while (causes.length < 3 && (cause = cause.cause)) {
|
|
366
|
+
causes.push({
|
|
367
|
+
class: cause.name,
|
|
368
|
+
message: cause.message,
|
|
369
|
+
backtrace: typeof cause.stack == 'string' ? makeBacktrace(cause.stack, false, logger) : null
|
|
370
|
+
});
|
|
371
|
+
}
|
|
372
|
+
return causes;
|
|
373
|
+
}
|
|
374
|
+
return [];
|
|
375
|
+
}
|
|
376
|
+
exports.getCauses = getCauses;
|
|
377
|
+
function getSourceForBacktrace(backtrace, getSourceFileHandler) {
|
|
378
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
379
|
+
var result, index, trace, fileContent;
|
|
380
|
+
return __generator(this, function (_a) {
|
|
381
|
+
switch (_a.label) {
|
|
382
|
+
case 0:
|
|
383
|
+
result = [];
|
|
384
|
+
if (!getSourceFileHandler || !backtrace || !backtrace.length) {
|
|
385
|
+
return [2 /*return*/, result];
|
|
386
|
+
}
|
|
387
|
+
index = 0;
|
|
388
|
+
_a.label = 1;
|
|
389
|
+
case 1:
|
|
390
|
+
if (!backtrace.length) return [3 /*break*/, 3];
|
|
391
|
+
trace = backtrace.splice(0)[index];
|
|
392
|
+
return [4 /*yield*/, getSourceFileHandler(trace.file)];
|
|
393
|
+
case 2:
|
|
394
|
+
fileContent = _a.sent();
|
|
395
|
+
result[index] = getSourceCodeSnippet(fileContent, trace.number, trace.column, 2);
|
|
396
|
+
index++;
|
|
397
|
+
return [3 /*break*/, 1];
|
|
398
|
+
case 3: return [2 /*return*/, result];
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
});
|
|
402
|
+
}
|
|
403
|
+
exports.getSourceForBacktrace = getSourceForBacktrace;
|
|
404
|
+
function runBeforeNotifyHandlers(notice, handlers) {
|
|
405
|
+
var results = [];
|
|
406
|
+
var result = true;
|
|
407
|
+
for (var i = 0, len = handlers.length; i < len; i++) {
|
|
408
|
+
var handler = handlers[i];
|
|
409
|
+
var handlerResult = handler(notice);
|
|
410
|
+
if (handlerResult === false) {
|
|
411
|
+
result = false;
|
|
412
|
+
}
|
|
413
|
+
results.push(handlerResult);
|
|
414
|
+
}
|
|
415
|
+
return {
|
|
416
|
+
results: results,
|
|
417
|
+
result: result
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
exports.runBeforeNotifyHandlers = runBeforeNotifyHandlers;
|
|
421
|
+
function runBeforeEventHandlers(payload, handlers, logger) {
|
|
422
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
423
|
+
var i, len, result, err_1;
|
|
424
|
+
return __generator(this, function (_a) {
|
|
425
|
+
switch (_a.label) {
|
|
426
|
+
case 0:
|
|
427
|
+
i = 0, len = handlers.length;
|
|
428
|
+
_a.label = 1;
|
|
429
|
+
case 1:
|
|
430
|
+
if (!(i < len)) return [3 /*break*/, 7];
|
|
431
|
+
result = void 0;
|
|
432
|
+
_a.label = 2;
|
|
433
|
+
case 2:
|
|
434
|
+
_a.trys.push([2, 4, , 5]);
|
|
435
|
+
return [4 /*yield*/, handlers[i](payload)];
|
|
436
|
+
case 3:
|
|
437
|
+
result = _a.sent();
|
|
438
|
+
return [3 /*break*/, 5];
|
|
439
|
+
case 4:
|
|
440
|
+
err_1 = _a.sent();
|
|
441
|
+
// A buggy handler should not suppress unrelated events. Log and treat as no-op.
|
|
442
|
+
logger === null || logger === void 0 ? void 0 : logger.error('beforeEvent handler threw; continuing', err_1);
|
|
443
|
+
return [3 /*break*/, 6];
|
|
444
|
+
case 5:
|
|
445
|
+
if (result === false) {
|
|
446
|
+
return [2 /*return*/, false];
|
|
447
|
+
}
|
|
448
|
+
_a.label = 6;
|
|
449
|
+
case 6:
|
|
450
|
+
i++;
|
|
451
|
+
return [3 /*break*/, 1];
|
|
452
|
+
case 7: return [2 /*return*/, true];
|
|
453
|
+
}
|
|
454
|
+
});
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
exports.runBeforeEventHandlers = runBeforeEventHandlers;
|
|
458
|
+
function resolveInsights(config) {
|
|
459
|
+
var _a, _b;
|
|
460
|
+
var insights = config.insights;
|
|
461
|
+
if (!insights || insights.enabled !== true) {
|
|
462
|
+
return { console: false, http: false };
|
|
463
|
+
}
|
|
464
|
+
return {
|
|
465
|
+
console: (_a = insights.console) !== null && _a !== void 0 ? _a : false,
|
|
466
|
+
http: (_b = insights.http) !== null && _b !== void 0 ? _b : false,
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
exports.resolveInsights = resolveInsights;
|
|
470
|
+
function fnv1a(str) {
|
|
471
|
+
var h = 0x811c9dc5;
|
|
472
|
+
for (var i = 0, len = str.length; i < len; i++) {
|
|
473
|
+
h ^= str.charCodeAt(i);
|
|
474
|
+
h = Math.imul(h, 0x01000193);
|
|
475
|
+
}
|
|
476
|
+
return h >>> 0;
|
|
477
|
+
}
|
|
478
|
+
function clampSampleRate(rate) {
|
|
479
|
+
if (rate < 0)
|
|
480
|
+
return 0;
|
|
481
|
+
if (rate > 100)
|
|
482
|
+
return 100;
|
|
483
|
+
return rate;
|
|
484
|
+
}
|
|
485
|
+
function shouldSampleEvent(event, configRate) {
|
|
486
|
+
var meta = event._hb;
|
|
487
|
+
var override = meta && Number.isFinite(meta.sampleRate) ? meta.sampleRate : undefined;
|
|
488
|
+
var rawRate = override !== undefined ? override : configRate;
|
|
489
|
+
// Guard against non-finite rates (e.g. NaN from Number(invalidConfig)); an
|
|
490
|
+
// unusable rate must not silently drop every event, so fall back to send-all.
|
|
491
|
+
var rate = clampSampleRate(Number.isFinite(rawRate) ? rawRate : 100);
|
|
492
|
+
if (rate <= 0)
|
|
493
|
+
return false;
|
|
494
|
+
if (rate >= 100)
|
|
495
|
+
return true;
|
|
496
|
+
var requestId = event.request_id;
|
|
497
|
+
if (typeof requestId === 'string' && requestId.length > 0) {
|
|
498
|
+
return fnv1a(requestId) % 100 < rate;
|
|
499
|
+
}
|
|
500
|
+
return Math.random() * 100 < rate;
|
|
501
|
+
}
|
|
502
|
+
exports.shouldSampleEvent = shouldSampleEvent;
|
|
503
|
+
function runAfterNotifyHandlers(notice, handlers, error) {
|
|
504
|
+
if (notice && notice.afterNotify) {
|
|
505
|
+
notice.afterNotify(error, notice);
|
|
506
|
+
}
|
|
507
|
+
for (var i = 0, len = handlers.length; i < len; i++) {
|
|
508
|
+
handlers[i](error, notice);
|
|
509
|
+
}
|
|
510
|
+
return true;
|
|
511
|
+
}
|
|
512
|
+
exports.runAfterNotifyHandlers = runAfterNotifyHandlers;
|
|
513
|
+
// Returns a new object with properties from other object.
|
|
514
|
+
function shallowClone(obj) {
|
|
515
|
+
if (typeof (obj) !== 'object' || obj === null) {
|
|
516
|
+
return {};
|
|
517
|
+
}
|
|
518
|
+
var result = {};
|
|
519
|
+
for (var k in obj) {
|
|
520
|
+
result[k] = obj[k];
|
|
521
|
+
}
|
|
522
|
+
return result;
|
|
523
|
+
}
|
|
524
|
+
exports.shallowClone = shallowClone;
|
|
525
|
+
function sanitize(obj, maxDepth) {
|
|
526
|
+
if (maxDepth === void 0) { maxDepth = 8; }
|
|
527
|
+
var seenObjects = [];
|
|
528
|
+
function seen(obj) {
|
|
529
|
+
if (!obj || typeof (obj) !== 'object') {
|
|
530
|
+
return false;
|
|
531
|
+
}
|
|
532
|
+
for (var i = 0; i < seenObjects.length; i++) {
|
|
533
|
+
var value = seenObjects[i];
|
|
534
|
+
if (value === obj) {
|
|
535
|
+
return true;
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
seenObjects.push(obj);
|
|
539
|
+
return false;
|
|
540
|
+
}
|
|
541
|
+
function canSerialize(obj) {
|
|
542
|
+
var typeOfObj = typeof obj;
|
|
543
|
+
// Functions are TMI
|
|
544
|
+
if (/function/.test(typeOfObj)) {
|
|
545
|
+
// Let special toJSON method pass as it's used by JSON.stringify (#722)
|
|
546
|
+
return obj.name === 'toJSON';
|
|
547
|
+
}
|
|
548
|
+
// Symbols can't convert to strings.
|
|
549
|
+
if (/symbol/.test(typeOfObj)) {
|
|
550
|
+
return false;
|
|
551
|
+
}
|
|
552
|
+
if (obj === null) {
|
|
553
|
+
return false;
|
|
554
|
+
}
|
|
555
|
+
// No prototype, likely created with `Object.create(null)`.
|
|
556
|
+
if (typeof obj === 'object' && typeof obj.hasOwnProperty === 'undefined') {
|
|
557
|
+
return false;
|
|
558
|
+
}
|
|
559
|
+
return true;
|
|
560
|
+
}
|
|
561
|
+
function serialize(obj, depth) {
|
|
562
|
+
if (depth === void 0) { depth = 0; }
|
|
563
|
+
if (depth >= maxDepth) {
|
|
564
|
+
return '[DEPTH]';
|
|
565
|
+
}
|
|
566
|
+
// Inspect invalid types
|
|
567
|
+
if (!canSerialize(obj)) {
|
|
568
|
+
return Object.prototype.toString.call(obj);
|
|
569
|
+
}
|
|
570
|
+
// Halt circular references
|
|
571
|
+
if (seen(obj)) {
|
|
572
|
+
return '[RECURSION]';
|
|
573
|
+
}
|
|
574
|
+
// Serialize inside arrays
|
|
575
|
+
if (Array.isArray(obj)) {
|
|
576
|
+
return obj.map(function (o) { return safeSerialize(o, depth + 1); });
|
|
577
|
+
}
|
|
578
|
+
// Serialize inside objects
|
|
579
|
+
if (typeof (obj) === 'object') {
|
|
580
|
+
var ret = {};
|
|
581
|
+
for (var k in obj) {
|
|
582
|
+
var v = obj[k];
|
|
583
|
+
if (Object.prototype.hasOwnProperty.call(obj, k) && (k != null) && (v != null)) {
|
|
584
|
+
ret[k] = safeSerialize(v, depth + 1);
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
return ret;
|
|
588
|
+
}
|
|
589
|
+
// Return everything else untouched
|
|
590
|
+
return obj;
|
|
591
|
+
}
|
|
592
|
+
function safeSerialize(obj, depth) {
|
|
593
|
+
if (depth === void 0) { depth = 0; }
|
|
594
|
+
try {
|
|
595
|
+
return serialize(obj, depth);
|
|
596
|
+
}
|
|
597
|
+
catch (e) {
|
|
598
|
+
return "[ERROR] ".concat(e);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
return safeSerialize(obj);
|
|
602
|
+
}
|
|
603
|
+
exports.sanitize = sanitize;
|
|
604
|
+
function logger(client) {
|
|
605
|
+
var log = function (method) {
|
|
606
|
+
return function () {
|
|
607
|
+
var _a;
|
|
608
|
+
var args = [];
|
|
609
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
610
|
+
args[_i] = arguments[_i];
|
|
611
|
+
}
|
|
612
|
+
if (method === 'debug') {
|
|
613
|
+
if (!client.config.debug) {
|
|
614
|
+
return;
|
|
615
|
+
}
|
|
616
|
+
// Log at default level so that you don't need to also enable verbose
|
|
617
|
+
// logging in Chrome.
|
|
618
|
+
method = 'log';
|
|
619
|
+
}
|
|
620
|
+
args.unshift('[Honeybadger]');
|
|
621
|
+
(_a = client.config.logger)[method].apply(_a, args);
|
|
622
|
+
};
|
|
623
|
+
};
|
|
624
|
+
return {
|
|
625
|
+
log: log('log'),
|
|
626
|
+
info: log('info'),
|
|
627
|
+
debug: log('debug'),
|
|
628
|
+
warn: log('warn'),
|
|
629
|
+
error: log('error')
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
exports.logger = logger;
|
|
633
|
+
/**
|
|
634
|
+
* Converts any object into a notice object (which at minimum has the same
|
|
635
|
+
* properties as Error, but supports additional Honeybadger properties.)
|
|
636
|
+
*/
|
|
637
|
+
function makeNotice(thing) {
|
|
638
|
+
var notice;
|
|
639
|
+
if (!thing) {
|
|
640
|
+
notice = {};
|
|
641
|
+
}
|
|
642
|
+
else if (isErrorObject(thing)) {
|
|
643
|
+
var e = thing;
|
|
644
|
+
notice = merge(thing, { name: e.name, message: e.message, stack: e.stack, cause: e.cause, originalError: e });
|
|
645
|
+
}
|
|
646
|
+
else if (typeof thing === 'object') {
|
|
647
|
+
notice = shallowClone(thing);
|
|
648
|
+
}
|
|
649
|
+
else {
|
|
650
|
+
var m = String(thing);
|
|
651
|
+
notice = { message: m };
|
|
652
|
+
}
|
|
653
|
+
return notice;
|
|
654
|
+
}
|
|
655
|
+
exports.makeNotice = makeNotice;
|
|
656
|
+
function isErrorObject(thing) {
|
|
657
|
+
return thing instanceof Error
|
|
658
|
+
|| Object.prototype.toString.call(thing) === '[object Error]'; // Important for cross-realm objects
|
|
659
|
+
}
|
|
660
|
+
exports.isErrorObject = isErrorObject;
|
|
661
|
+
/**
|
|
662
|
+
* Instrument an existing function inside an object (usually global).
|
|
663
|
+
* @param {!Object} object
|
|
664
|
+
* @param {!String} name
|
|
665
|
+
* @param {!Function} replacement
|
|
666
|
+
*/
|
|
667
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
668
|
+
function instrument(object, name, replacement) {
|
|
669
|
+
if (!object || !name || !replacement || !(name in object)) {
|
|
670
|
+
return;
|
|
671
|
+
}
|
|
672
|
+
try {
|
|
673
|
+
var original = object[name];
|
|
674
|
+
while (original && original.__hb_original) {
|
|
675
|
+
original = original.__hb_original;
|
|
676
|
+
}
|
|
677
|
+
object[name] = replacement(original);
|
|
678
|
+
object[name].__hb_original = original;
|
|
679
|
+
}
|
|
680
|
+
catch (_e) {
|
|
681
|
+
// Ignores errors where "original" is a restricted object (see #1001)
|
|
682
|
+
// Uncaught Error: Permission denied to access property "__hb_original"
|
|
683
|
+
// Also ignores:
|
|
684
|
+
// Error: TypeError: Cannot set property onunhandledrejection of [object Object] which has only a getter
|
|
685
|
+
// User-Agent: Mozilla/5.0 (Linux; Android 10; SAMSUNG SM-G960F) AppleWebKit/537.36 (KHTML, like Gecko) SamsungBrowser/12.1 Chrome/79.0.3945.136 Mobile Safari/537.36
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
exports.instrument = instrument;
|
|
689
|
+
var _consoleAlreadyInstrumented = false;
|
|
690
|
+
var listeners = [];
|
|
691
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
692
|
+
function instrumentConsole(_window, handler) {
|
|
693
|
+
if (!_window || !_window.console || !handler) {
|
|
694
|
+
return;
|
|
695
|
+
}
|
|
696
|
+
listeners.push(handler);
|
|
697
|
+
if (_consoleAlreadyInstrumented) {
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
700
|
+
_consoleAlreadyInstrumented = true;
|
|
701
|
+
['debug', 'info', 'warn', 'error', 'log'].forEach(function (level) {
|
|
702
|
+
instrument(_window.console, level, function hbLogger(original) {
|
|
703
|
+
return function () {
|
|
704
|
+
var args = Array.prototype.slice.call(arguments);
|
|
705
|
+
listeners.forEach(function (listener) {
|
|
706
|
+
try {
|
|
707
|
+
listener(level, args);
|
|
708
|
+
}
|
|
709
|
+
catch (_e) {
|
|
710
|
+
// ignore
|
|
711
|
+
// should never reach here because instrument method already wraps with try/catch block
|
|
712
|
+
}
|
|
713
|
+
});
|
|
714
|
+
if (typeof original === 'function') {
|
|
715
|
+
Function.prototype.apply.call(original, _window.console, arguments);
|
|
716
|
+
}
|
|
717
|
+
};
|
|
718
|
+
});
|
|
719
|
+
});
|
|
720
|
+
}
|
|
721
|
+
exports.instrumentConsole = instrumentConsole;
|
|
722
|
+
function endpoint(base, path) {
|
|
723
|
+
var endpoint = base.trim().replace(/\/$/, '');
|
|
724
|
+
path = path.trim().replace(/(^\/|\/$)/g, '');
|
|
725
|
+
return "".concat(endpoint, "/").concat(path);
|
|
726
|
+
}
|
|
727
|
+
exports.endpoint = endpoint;
|
|
728
|
+
function generateStackTrace() {
|
|
729
|
+
try {
|
|
730
|
+
throw new Error('');
|
|
731
|
+
}
|
|
732
|
+
catch (e) {
|
|
733
|
+
if (e.stack) {
|
|
734
|
+
return e.stack;
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
var maxStackSize = 10;
|
|
738
|
+
var stack = [];
|
|
739
|
+
var curr = arguments.callee;
|
|
740
|
+
while (curr && stack.length < maxStackSize) {
|
|
741
|
+
if (/function(?:\s+([\w$]+))+\s*\(/.test(curr.toString())) {
|
|
742
|
+
stack.push(RegExp.$1 || '<anonymous>');
|
|
743
|
+
}
|
|
744
|
+
else {
|
|
745
|
+
stack.push('<anonymous>');
|
|
746
|
+
}
|
|
747
|
+
try {
|
|
748
|
+
curr = curr.caller;
|
|
749
|
+
}
|
|
750
|
+
catch (e) {
|
|
751
|
+
break;
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
return stack.join('\n');
|
|
755
|
+
}
|
|
756
|
+
exports.generateStackTrace = generateStackTrace;
|
|
757
|
+
function filter(obj, filters) {
|
|
758
|
+
if (!is('Object', obj)) {
|
|
759
|
+
return;
|
|
760
|
+
}
|
|
761
|
+
if (!is('Array', filters)) {
|
|
762
|
+
filters = [];
|
|
763
|
+
}
|
|
764
|
+
var seen = [];
|
|
765
|
+
function filter(obj) {
|
|
766
|
+
var k, newObj;
|
|
767
|
+
if (is('Object', obj) || is('Array', obj)) {
|
|
768
|
+
if (seen.indexOf(obj) !== -1) {
|
|
769
|
+
return '[CIRCULAR DATA STRUCTURE]';
|
|
770
|
+
}
|
|
771
|
+
seen.push(obj);
|
|
772
|
+
}
|
|
773
|
+
if (is('Object', obj)) {
|
|
774
|
+
newObj = {};
|
|
775
|
+
for (k in obj) {
|
|
776
|
+
if (filterMatch(k, filters)) {
|
|
777
|
+
newObj[k] = '[FILTERED]';
|
|
778
|
+
}
|
|
779
|
+
else {
|
|
780
|
+
newObj[k] = filter(obj[k]);
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
return newObj;
|
|
784
|
+
}
|
|
785
|
+
if (is('Array', obj)) {
|
|
786
|
+
return obj.map(function (v) {
|
|
787
|
+
return filter(v);
|
|
788
|
+
});
|
|
789
|
+
}
|
|
790
|
+
if (is('Function', obj)) {
|
|
791
|
+
return '[FUNC]';
|
|
792
|
+
}
|
|
793
|
+
return obj;
|
|
794
|
+
}
|
|
795
|
+
return filter(obj);
|
|
796
|
+
}
|
|
797
|
+
exports.filter = filter;
|
|
798
|
+
function filterMatch(key, filters) {
|
|
799
|
+
for (var i = 0; i < filters.length; i++) {
|
|
800
|
+
if (key.toLowerCase().indexOf(filters[i].toLowerCase()) !== -1) {
|
|
801
|
+
return true;
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
return false;
|
|
805
|
+
}
|
|
806
|
+
function is(type, obj) {
|
|
807
|
+
var klass = Object.prototype.toString.call(obj).slice(8, -1);
|
|
808
|
+
return obj !== undefined && obj !== null && klass === type;
|
|
809
|
+
}
|
|
810
|
+
function filterUrl(url, filters) {
|
|
811
|
+
if (!filters) {
|
|
812
|
+
return url;
|
|
813
|
+
}
|
|
814
|
+
if (typeof url !== 'string') {
|
|
815
|
+
return url;
|
|
816
|
+
}
|
|
817
|
+
var query = url.split(/\?/, 2)[1];
|
|
818
|
+
if (!query) {
|
|
819
|
+
return url;
|
|
820
|
+
}
|
|
821
|
+
var result = url;
|
|
822
|
+
query.split(/[&]\s?/).forEach(function (pair) {
|
|
823
|
+
var _a = pair.split('=', 2), key = _a[0], value = _a[1];
|
|
824
|
+
if (filterMatch(key, filters)) {
|
|
825
|
+
result = result.replace("".concat(key, "=").concat(value), "".concat(key, "=[FILTERED]"));
|
|
826
|
+
}
|
|
827
|
+
});
|
|
828
|
+
return result;
|
|
829
|
+
}
|
|
830
|
+
exports.filterUrl = filterUrl;
|
|
831
|
+
function formatCGIData(vars, prefix) {
|
|
832
|
+
if (prefix === void 0) { prefix = ''; }
|
|
833
|
+
var formattedVars = {};
|
|
834
|
+
Object.keys(vars).forEach(function (key) {
|
|
835
|
+
var formattedKey = prefix + key.replace(/\W/g, '_').toUpperCase();
|
|
836
|
+
formattedVars[formattedKey] = vars[key];
|
|
837
|
+
});
|
|
838
|
+
return formattedVars;
|
|
839
|
+
}
|
|
840
|
+
exports.formatCGIData = formatCGIData;
|
|
841
|
+
function clone(obj) {
|
|
842
|
+
return JSON.parse(JSON.stringify(obj));
|
|
843
|
+
}
|
|
844
|
+
exports.clone = clone;
|
|
845
|
+
var THRESHOLD_COLUMN_NUMBER = 10000;
|
|
846
|
+
var THRESHOLD_LINE_LENGTH = 10000;
|
|
847
|
+
var THRESHOLD_FILE_SIZE = 200000; // 200KB threshold
|
|
848
|
+
function getThresholdExceededSnippet(lineNumber) {
|
|
849
|
+
var _a;
|
|
850
|
+
return _a = {}, _a[lineNumber] = 'SOURCE_SIZE_TOO_LARGE', _a;
|
|
851
|
+
}
|
|
852
|
+
function getSourceCodeSnippet(fileData, lineNumber, columnNumber, sourceRadius) {
|
|
853
|
+
if (sourceRadius === void 0) { sourceRadius = 2; }
|
|
854
|
+
if (!fileData) {
|
|
855
|
+
return null;
|
|
856
|
+
}
|
|
857
|
+
// If column number is provided and very high, it's likely a bundled/minified file
|
|
858
|
+
if (columnNumber && columnNumber > THRESHOLD_COLUMN_NUMBER) {
|
|
859
|
+
return getThresholdExceededSnippet(lineNumber);
|
|
860
|
+
}
|
|
861
|
+
// If file is very large, it's likely bundled
|
|
862
|
+
if (fileData.length > THRESHOLD_FILE_SIZE) {
|
|
863
|
+
return getThresholdExceededSnippet(lineNumber);
|
|
864
|
+
}
|
|
865
|
+
var lines = fileData.split('\n');
|
|
866
|
+
// add one empty line because array index starts from 0, but error line number is counted from 1
|
|
867
|
+
lines.unshift('');
|
|
868
|
+
// Check if the target line is extremely long
|
|
869
|
+
var targetLine = lines[lineNumber];
|
|
870
|
+
if (targetLine && targetLine.length > THRESHOLD_LINE_LENGTH) {
|
|
871
|
+
return getThresholdExceededSnippet(lineNumber);
|
|
872
|
+
}
|
|
873
|
+
var start = lineNumber - sourceRadius;
|
|
874
|
+
var end = lineNumber + sourceRadius;
|
|
875
|
+
var result = {};
|
|
876
|
+
for (var i = start; i <= end; i++) {
|
|
877
|
+
var line = lines[i];
|
|
878
|
+
if (typeof line === 'string') {
|
|
879
|
+
result[i] = line;
|
|
880
|
+
}
|
|
881
|
+
}
|
|
882
|
+
return result;
|
|
883
|
+
}
|
|
884
|
+
function isBrowserConfig(config) {
|
|
885
|
+
return config.async !== undefined;
|
|
886
|
+
}
|
|
887
|
+
exports.isBrowserConfig = isBrowserConfig;
|
|
888
|
+
/** globalThis has fairly good support. But just in case, lets check its defined.
|
|
889
|
+
* @see {https://caniuse.com/?search=globalThis}
|
|
890
|
+
*/
|
|
891
|
+
function globalThisOrWindow() {
|
|
892
|
+
if (typeof globalThis !== 'undefined') {
|
|
893
|
+
return globalThis;
|
|
894
|
+
}
|
|
895
|
+
if (typeof self !== 'undefined') {
|
|
896
|
+
return self;
|
|
897
|
+
}
|
|
898
|
+
return window;
|
|
899
|
+
}
|
|
900
|
+
exports.globalThisOrWindow = globalThisOrWindow;
|
|
901
|
+
var _deprecatedMethodCalls = {};
|
|
902
|
+
/**
|
|
903
|
+
* Logs a deprecation warning, every X calls to the method.
|
|
904
|
+
*/
|
|
905
|
+
function logDeprecatedMethod(logger, oldMethod, newMethod, callCountThreshold) {
|
|
906
|
+
if (callCountThreshold === void 0) { callCountThreshold = 100; }
|
|
907
|
+
var key = "".concat(oldMethod, "-").concat(newMethod);
|
|
908
|
+
if (typeof _deprecatedMethodCalls[key] === 'undefined') {
|
|
909
|
+
_deprecatedMethodCalls[key] = 0;
|
|
910
|
+
}
|
|
911
|
+
if (_deprecatedMethodCalls[key] % callCountThreshold !== 0) {
|
|
912
|
+
_deprecatedMethodCalls[key]++;
|
|
913
|
+
return;
|
|
914
|
+
}
|
|
915
|
+
var msg = "Deprecation warning: ".concat(oldMethod, " has been deprecated; please use ").concat(newMethod, " instead.");
|
|
916
|
+
logger.warn(msg);
|
|
917
|
+
_deprecatedMethodCalls[key]++;
|
|
918
|
+
}
|
|
919
|
+
exports.logDeprecatedMethod = logDeprecatedMethod;
|
|
920
|
+
|
|
921
|
+
} (util));
|
|
922
|
+
|
|
923
|
+
Object.defineProperty(console_events, "__esModule", { value: true });
|
|
924
|
+
var util_1$3 = util;
|
|
925
|
+
function default_1(_window) {
|
|
926
|
+
if (_window === void 0) { _window = (0, util_1$3.globalThisOrWindow)(); }
|
|
927
|
+
return {
|
|
928
|
+
shouldReloadOnConfigure: false,
|
|
929
|
+
load: function (client) {
|
|
930
|
+
function sendEventsToInsights() {
|
|
931
|
+
return (0, util_1$3.resolveInsights)(client.config).console;
|
|
932
|
+
}
|
|
933
|
+
if (!sendEventsToInsights()) {
|
|
934
|
+
return;
|
|
935
|
+
}
|
|
936
|
+
(0, util_1$3.instrumentConsole)(_window, function (level, args) {
|
|
937
|
+
if (!sendEventsToInsights()) {
|
|
938
|
+
return;
|
|
939
|
+
}
|
|
940
|
+
if (args.length === 0) {
|
|
941
|
+
return;
|
|
942
|
+
}
|
|
943
|
+
var data = {
|
|
944
|
+
severity: level,
|
|
945
|
+
};
|
|
946
|
+
if (typeof args[0] === 'string') {
|
|
947
|
+
data.message = args[0];
|
|
948
|
+
data.args = args.slice(1);
|
|
949
|
+
}
|
|
950
|
+
else {
|
|
951
|
+
data.args = args;
|
|
952
|
+
}
|
|
953
|
+
client.event('log', data);
|
|
954
|
+
});
|
|
955
|
+
}
|
|
956
|
+
};
|
|
957
|
+
}
|
|
958
|
+
console_events.default = default_1;
|
|
959
|
+
|
|
960
|
+
var client = {};
|
|
961
|
+
|
|
962
|
+
var store = {};
|
|
963
|
+
|
|
964
|
+
Object.defineProperty(store, "__esModule", { value: true });
|
|
965
|
+
store.GlobalStore = void 0;
|
|
966
|
+
var util_1$2 = util;
|
|
967
|
+
var GlobalStore = /** @class */ (function () {
|
|
968
|
+
function GlobalStore(contents, breadcrumbsLimit) {
|
|
969
|
+
this.contents = contents;
|
|
970
|
+
this.breadcrumbsLimit = breadcrumbsLimit;
|
|
971
|
+
}
|
|
972
|
+
GlobalStore.create = function (contents, breadcrumbsLimit) {
|
|
973
|
+
return new GlobalStore(contents, breadcrumbsLimit);
|
|
974
|
+
};
|
|
975
|
+
GlobalStore.prototype.available = function () {
|
|
976
|
+
return true;
|
|
977
|
+
};
|
|
978
|
+
GlobalStore.prototype.getContents = function (key) {
|
|
979
|
+
var value = key ? this.contents[key] : this.contents;
|
|
980
|
+
return JSON.parse(JSON.stringify(value));
|
|
981
|
+
};
|
|
982
|
+
GlobalStore.prototype.setContext = function (context) {
|
|
983
|
+
this.contents.context = (0, util_1$2.merge)(this.contents.context, context || {});
|
|
984
|
+
};
|
|
985
|
+
GlobalStore.prototype.setEventContext = function (eventContext) {
|
|
986
|
+
this.contents.eventContext = (0, util_1$2.merge)(this.contents.eventContext, eventContext || {});
|
|
987
|
+
};
|
|
988
|
+
GlobalStore.prototype.clearEventContext = function () {
|
|
989
|
+
this.contents.eventContext = {};
|
|
990
|
+
};
|
|
991
|
+
GlobalStore.prototype.addBreadcrumb = function (breadcrumb) {
|
|
992
|
+
if (this.contents.breadcrumbs.length == this.breadcrumbsLimit) {
|
|
993
|
+
this.contents.breadcrumbs.shift();
|
|
994
|
+
}
|
|
995
|
+
this.contents.breadcrumbs.push(breadcrumb);
|
|
996
|
+
};
|
|
997
|
+
GlobalStore.prototype.clear = function () {
|
|
998
|
+
this.contents.context = {};
|
|
999
|
+
this.contents.eventContext = {};
|
|
1000
|
+
this.contents.breadcrumbs = [];
|
|
1001
|
+
};
|
|
1002
|
+
GlobalStore.prototype.run = function (callback) {
|
|
1003
|
+
return callback();
|
|
1004
|
+
};
|
|
1005
|
+
return GlobalStore;
|
|
1006
|
+
}());
|
|
1007
|
+
store.GlobalStore = GlobalStore;
|
|
1008
|
+
|
|
1009
|
+
var throttled_events_worker = {};
|
|
1010
|
+
|
|
1011
|
+
class NdJson {
|
|
1012
|
+
static parse(data) {
|
|
1013
|
+
const lines = data.trim().split('\n');
|
|
1014
|
+
return lines.map(line => JSON.parse(line));
|
|
1015
|
+
}
|
|
1016
|
+
static stringify(data) {
|
|
1017
|
+
return data.map(item => JSON.stringify(item)).join('\n');
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
var module$1 = /*#__PURE__*/Object.freeze({
|
|
1022
|
+
__proto__: null,
|
|
1023
|
+
NdJson: NdJson
|
|
1024
|
+
});
|
|
1025
|
+
|
|
1026
|
+
var require$$0 = /*@__PURE__*/getAugmentedNamespace(module$1);
|
|
1027
|
+
|
|
1028
|
+
var defaults = {};
|
|
1029
|
+
|
|
1030
|
+
Object.defineProperty(defaults, "__esModule", { value: true });
|
|
1031
|
+
defaults.BREADCRUMBS_SELECTOR_ATTRIBUTES = defaults.CONFIG = void 0;
|
|
1032
|
+
defaults.CONFIG = {
|
|
1033
|
+
apiKey: null,
|
|
1034
|
+
endpoint: 'https://api.honeybadger.io',
|
|
1035
|
+
appEndpoint: 'https://app.honeybadger.io',
|
|
1036
|
+
environment: null,
|
|
1037
|
+
hostname: null,
|
|
1038
|
+
projectRoot: null,
|
|
1039
|
+
component: null,
|
|
1040
|
+
action: null,
|
|
1041
|
+
revision: null,
|
|
1042
|
+
reportData: null,
|
|
1043
|
+
breadcrumbsEnabled: true,
|
|
1044
|
+
// deprecated: `eventsEnabled: true` auto-enables insights.enabled + insights.console
|
|
1045
|
+
eventsEnabled: false,
|
|
1046
|
+
insights: {
|
|
1047
|
+
enabled: false,
|
|
1048
|
+
console: false,
|
|
1049
|
+
http: false,
|
|
1050
|
+
},
|
|
1051
|
+
events: {
|
|
1052
|
+
dispatchIntervalSeconds: 10,
|
|
1053
|
+
bulkThreshold: 500,
|
|
1054
|
+
sampleRatePercentage: 100,
|
|
1055
|
+
},
|
|
1056
|
+
maxBreadcrumbs: 40,
|
|
1057
|
+
maxObjectDepth: 8,
|
|
1058
|
+
logger: console,
|
|
1059
|
+
developmentEnvironments: ['dev', 'development', 'test'],
|
|
1060
|
+
debug: false,
|
|
1061
|
+
tags: null,
|
|
1062
|
+
enableUncaught: true,
|
|
1063
|
+
enableUnhandledRejection: true,
|
|
1064
|
+
afterUncaught: function () { return true; },
|
|
1065
|
+
filters: ['creditcard', 'password'],
|
|
1066
|
+
__plugins: [],
|
|
1067
|
+
};
|
|
1068
|
+
// Browser-only, so it lives outside CONFIG (which is shared with Node).
|
|
1069
|
+
defaults.BREADCRUMBS_SELECTOR_ATTRIBUTES = ['data-hb-name'];
|
|
1070
|
+
|
|
1071
|
+
var __assign$1 = (commonjsGlobal && commonjsGlobal.__assign) || function () {
|
|
1072
|
+
__assign$1 = Object.assign || function(t) {
|
|
1073
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
1074
|
+
s = arguments[i];
|
|
1075
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
1076
|
+
t[p] = s[p];
|
|
1077
|
+
}
|
|
1078
|
+
return t;
|
|
1079
|
+
};
|
|
1080
|
+
return __assign$1.apply(this, arguments);
|
|
1081
|
+
};
|
|
1082
|
+
var __awaiter$1 = (commonjsGlobal && commonjsGlobal.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
1083
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
1084
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
1085
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
1086
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
1087
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
1088
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
1089
|
+
});
|
|
1090
|
+
};
|
|
1091
|
+
var __generator$1 = (commonjsGlobal && commonjsGlobal.__generator) || function (thisArg, body) {
|
|
1092
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
1093
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
1094
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
1095
|
+
function step(op) {
|
|
1096
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
1097
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
1098
|
+
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;
|
|
1099
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
1100
|
+
switch (op[0]) {
|
|
1101
|
+
case 0: case 1: t = op; break;
|
|
1102
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
1103
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
1104
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
1105
|
+
default:
|
|
1106
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
1107
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
1108
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
1109
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
1110
|
+
if (t[2]) _.ops.pop();
|
|
1111
|
+
_.trys.pop(); continue;
|
|
1112
|
+
}
|
|
1113
|
+
op = body.call(thisArg, _);
|
|
1114
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
1115
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
1116
|
+
}
|
|
1117
|
+
};
|
|
1118
|
+
Object.defineProperty(throttled_events_worker, "__esModule", { value: true });
|
|
1119
|
+
throttled_events_worker.ThrottledEventsWorker = void 0;
|
|
1120
|
+
var json_nd_1 = require$$0;
|
|
1121
|
+
var util_1$1 = util;
|
|
1122
|
+
var defaults_1$1 = defaults;
|
|
1123
|
+
var ThrottledEventsWorker = /** @class */ (function () {
|
|
1124
|
+
function ThrottledEventsWorker(config, transport) {
|
|
1125
|
+
this.config = config;
|
|
1126
|
+
this.transport = transport;
|
|
1127
|
+
this.queue = [];
|
|
1128
|
+
this.cooldownTimer = null;
|
|
1129
|
+
// Timestamp (ms) until which the post-send cooldown window is active. A timer
|
|
1130
|
+
// is only armed while there are queued events waiting for this window; when the
|
|
1131
|
+
// queue drains empty we keep the timestamp but drop the timer, so an idle worker
|
|
1132
|
+
// never holds a pending timer (which would otherwise keep a Node process alive
|
|
1133
|
+
// for the full interval.
|
|
1134
|
+
this.cooldownUntil = 0;
|
|
1135
|
+
this.inFlight = null;
|
|
1136
|
+
this.config = __assign$1(__assign$1({}, defaults_1$1.CONFIG), config);
|
|
1137
|
+
this.logger = this.originalLogger();
|
|
1138
|
+
}
|
|
1139
|
+
ThrottledEventsWorker.prototype.configure = function (opts) {
|
|
1140
|
+
for (var k in opts) {
|
|
1141
|
+
this.config[k] = opts[k];
|
|
1142
|
+
}
|
|
1143
|
+
};
|
|
1144
|
+
ThrottledEventsWorker.prototype.log = function (payload) {
|
|
1145
|
+
this.queue.push(payload);
|
|
1146
|
+
if (this.inFlight) {
|
|
1147
|
+
return;
|
|
1148
|
+
}
|
|
1149
|
+
// Crossing the bulk threshold preempts any pending cooldown and dispatches now.
|
|
1150
|
+
if (this.queue.length >= this.bulkThreshold()) {
|
|
1151
|
+
this.clearCooldownTimer();
|
|
1152
|
+
this.processQueue();
|
|
1153
|
+
return;
|
|
1154
|
+
}
|
|
1155
|
+
// A timer is already counting down the cooldown window; the queued event
|
|
1156
|
+
// will be picked up when it fires.
|
|
1157
|
+
if (this.cooldownTimer) {
|
|
1158
|
+
return;
|
|
1159
|
+
}
|
|
1160
|
+
// We're inside a cooldown window but no timer is armed (the queue had drained
|
|
1161
|
+
// empty after the previous send). Arm one for the remaining time so this event
|
|
1162
|
+
// still respects the interval.
|
|
1163
|
+
var remaining = this.cooldownRemainingMs();
|
|
1164
|
+
if (remaining > 0) {
|
|
1165
|
+
this.scheduleCooldownTimer(remaining);
|
|
1166
|
+
return;
|
|
1167
|
+
}
|
|
1168
|
+
this.processQueue();
|
|
1169
|
+
};
|
|
1170
|
+
ThrottledEventsWorker.prototype.flushAsync = function () {
|
|
1171
|
+
var _this = this;
|
|
1172
|
+
var _a;
|
|
1173
|
+
this.logger.debug('[Honeybadger] Flushing events');
|
|
1174
|
+
this.clearCooldownTimer();
|
|
1175
|
+
var previous = (_a = this.inFlight) !== null && _a !== void 0 ? _a : Promise.resolve();
|
|
1176
|
+
var flush = previous.then(function () { return _this.drainAll(); });
|
|
1177
|
+
// Mark the flush as in-flight so a concurrent log() doesn't start an
|
|
1178
|
+
// overlapping processQueue() drain while we're draining here.
|
|
1179
|
+
this.inFlight = flush;
|
|
1180
|
+
var clear = function () {
|
|
1181
|
+
if (_this.inFlight === flush) {
|
|
1182
|
+
_this.inFlight = null;
|
|
1183
|
+
}
|
|
1184
|
+
};
|
|
1185
|
+
flush.then(clear, clear);
|
|
1186
|
+
return flush;
|
|
1187
|
+
};
|
|
1188
|
+
ThrottledEventsWorker.prototype.drainAll = function () {
|
|
1189
|
+
return __awaiter$1(this, void 0, void 0, function () {
|
|
1190
|
+
return __generator$1(this, function (_a) {
|
|
1191
|
+
switch (_a.label) {
|
|
1192
|
+
case 0:
|
|
1193
|
+
if (!(this.queue.length > 0)) return [3 /*break*/, 2];
|
|
1194
|
+
return [4 /*yield*/, this.send()];
|
|
1195
|
+
case 1:
|
|
1196
|
+
_a.sent();
|
|
1197
|
+
return [3 /*break*/, 0];
|
|
1198
|
+
case 2: return [2 /*return*/];
|
|
1199
|
+
}
|
|
1200
|
+
});
|
|
1201
|
+
});
|
|
1202
|
+
};
|
|
1203
|
+
ThrottledEventsWorker.prototype.processQueue = function () {
|
|
1204
|
+
var _this = this;
|
|
1205
|
+
if (this.queue.length === 0 || this.inFlight) {
|
|
1206
|
+
return;
|
|
1207
|
+
}
|
|
1208
|
+
var inFlight = this.send()
|
|
1209
|
+
.catch(function (error) {
|
|
1210
|
+
_this.logger.error('[Honeybadger] Error making HTTP request:', error);
|
|
1211
|
+
})
|
|
1212
|
+
.then(function () {
|
|
1213
|
+
// Only reset if we're still the current operation; a flushAsync() may
|
|
1214
|
+
// have taken ownership of inFlight while this send was resolving.
|
|
1215
|
+
if (_this.inFlight === inFlight) {
|
|
1216
|
+
_this.inFlight = null;
|
|
1217
|
+
_this.scheduleNextDispatch();
|
|
1218
|
+
}
|
|
1219
|
+
});
|
|
1220
|
+
this.inFlight = inFlight;
|
|
1221
|
+
};
|
|
1222
|
+
ThrottledEventsWorker.prototype.scheduleNextDispatch = function () {
|
|
1223
|
+
var intervalMs = this.dispatchIntervalMs();
|
|
1224
|
+
// Capture the cooldown deadline at dispatch time so a later config change to
|
|
1225
|
+
// the interval doesn't retroactively shorten a window already in progress.
|
|
1226
|
+
this.cooldownUntil = Date.now() + intervalMs;
|
|
1227
|
+
if (this.queue.length >= this.bulkThreshold()) {
|
|
1228
|
+
this.processQueue();
|
|
1229
|
+
return;
|
|
1230
|
+
}
|
|
1231
|
+
// Only arm a timer when there's queued work waiting for it. If the queue is
|
|
1232
|
+
// empty, `cooldownUntil` alone enforces the window: the next log() will arm a
|
|
1233
|
+
// timer for whatever time remains, and an idle worker holds no timer at all.
|
|
1234
|
+
if (this.queue.length > 0) {
|
|
1235
|
+
this.scheduleCooldownTimer(intervalMs);
|
|
1236
|
+
}
|
|
1237
|
+
};
|
|
1238
|
+
ThrottledEventsWorker.prototype.cooldownRemainingMs = function () {
|
|
1239
|
+
if (!this.cooldownUntil) {
|
|
1240
|
+
return 0;
|
|
1241
|
+
}
|
|
1242
|
+
return Math.max(0, this.cooldownUntil - Date.now());
|
|
1243
|
+
};
|
|
1244
|
+
ThrottledEventsWorker.prototype.scheduleCooldownTimer = function (ms) {
|
|
1245
|
+
var _this = this;
|
|
1246
|
+
this.cooldownTimer = setTimeout(function () {
|
|
1247
|
+
_this.cooldownTimer = null;
|
|
1248
|
+
_this.processQueue();
|
|
1249
|
+
}, ms);
|
|
1250
|
+
// In Node, don't let a pending cooldown timer keep the process alive for the
|
|
1251
|
+
// whole batching interval. `unref` lets the event loop go idle so the process
|
|
1252
|
+
// can exit (or a shutdown / `beforeExit` handler can run) promptly instead of
|
|
1253
|
+
// blocking for `dispatchIntervalSeconds`. Queued events aren't lost: a
|
|
1254
|
+
// `flushAsync()` on the way out still drains them before exit. (`unref` is
|
|
1255
|
+
// Node-only; the browser's numeric setTimeout handle has no such method.)
|
|
1256
|
+
if (typeof this.cooldownTimer === 'object' && this.cooldownTimer !== null && typeof this.cooldownTimer.unref === 'function') {
|
|
1257
|
+
this.cooldownTimer.unref();
|
|
1258
|
+
}
|
|
1259
|
+
};
|
|
1260
|
+
ThrottledEventsWorker.prototype.clearCooldownTimer = function () {
|
|
1261
|
+
if (this.cooldownTimer) {
|
|
1262
|
+
clearTimeout(this.cooldownTimer);
|
|
1263
|
+
this.cooldownTimer = null;
|
|
1264
|
+
}
|
|
1265
|
+
};
|
|
1266
|
+
ThrottledEventsWorker.prototype.send = function () {
|
|
1267
|
+
return __awaiter$1(this, void 0, void 0, function () {
|
|
1268
|
+
var eventsData, data;
|
|
1269
|
+
return __generator$1(this, function (_a) {
|
|
1270
|
+
if (this.queue.length === 0) {
|
|
1271
|
+
return [2 /*return*/];
|
|
1272
|
+
}
|
|
1273
|
+
eventsData = this.queue.splice(0, this.bulkThreshold());
|
|
1274
|
+
data = json_nd_1.NdJson.stringify(eventsData);
|
|
1275
|
+
return [2 /*return*/, this.makeHttpRequest(data)];
|
|
1276
|
+
});
|
|
1277
|
+
});
|
|
1278
|
+
};
|
|
1279
|
+
ThrottledEventsWorker.prototype.bulkThreshold = function () {
|
|
1280
|
+
var _a;
|
|
1281
|
+
var v = (_a = this.config.events) === null || _a === void 0 ? void 0 : _a.bulkThreshold;
|
|
1282
|
+
return typeof v === 'number' && v > 0 ? v : defaults_1$1.CONFIG.events.bulkThreshold;
|
|
1283
|
+
};
|
|
1284
|
+
ThrottledEventsWorker.prototype.dispatchIntervalMs = function () {
|
|
1285
|
+
var _a;
|
|
1286
|
+
var v = (_a = this.config.events) === null || _a === void 0 ? void 0 : _a.dispatchIntervalSeconds;
|
|
1287
|
+
var seconds = typeof v === 'number' && v >= 0 ? v : defaults_1$1.CONFIG.events.dispatchIntervalSeconds;
|
|
1288
|
+
return seconds * 1000;
|
|
1289
|
+
};
|
|
1290
|
+
ThrottledEventsWorker.prototype.makeHttpRequest = function (data) {
|
|
1291
|
+
return __awaiter$1(this, void 0, void 0, function () {
|
|
1292
|
+
var _this = this;
|
|
1293
|
+
return __generator$1(this, function (_a) {
|
|
1294
|
+
return [2 /*return*/, this.transport
|
|
1295
|
+
.send({
|
|
1296
|
+
headers: {
|
|
1297
|
+
'X-API-Key': this.config.apiKey,
|
|
1298
|
+
'Content-Type': 'application/json',
|
|
1299
|
+
},
|
|
1300
|
+
method: 'POST',
|
|
1301
|
+
endpoint: (0, util_1$1.endpoint)(this.config.endpoint, '/v1/events'),
|
|
1302
|
+
maxObjectDepth: this.config.maxObjectDepth,
|
|
1303
|
+
logger: this.logger,
|
|
1304
|
+
}, data)
|
|
1305
|
+
.then(function (resp) {
|
|
1306
|
+
if ([200, 201].includes(resp.statusCode)) {
|
|
1307
|
+
_this.logger.debug('[Honeybadger] Events sent successfully');
|
|
1308
|
+
}
|
|
1309
|
+
else {
|
|
1310
|
+
_this.logger.debug("[Honeybadger] Events failed[".concat(resp.statusCode, "]: ").concat(resp.body));
|
|
1311
|
+
}
|
|
1312
|
+
})
|
|
1313
|
+
.catch(function (err) {
|
|
1314
|
+
_this.logger.error("[Honeybadger] Error sending events: ".concat(err.message));
|
|
1315
|
+
})];
|
|
1316
|
+
});
|
|
1317
|
+
});
|
|
1318
|
+
};
|
|
1319
|
+
/**
|
|
1320
|
+
* todo: improve this
|
|
1321
|
+
*
|
|
1322
|
+
* The events plugin overrides the console methods to enable automatic instrumentation
|
|
1323
|
+
* of console logs to the Honeybadger API.
|
|
1324
|
+
* So if we want to log something in here we need to use the original methods.
|
|
1325
|
+
*/
|
|
1326
|
+
ThrottledEventsWorker.prototype.originalLogger = function () {
|
|
1327
|
+
var _this = this;
|
|
1328
|
+
var _a, _b, _c, _d;
|
|
1329
|
+
return {
|
|
1330
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1331
|
+
log: (_a = console.log.__hb_original) !== null && _a !== void 0 ? _a : console.log,
|
|
1332
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1333
|
+
info: (_b = console.info.__hb_original) !== null && _b !== void 0 ? _b : console.info,
|
|
1334
|
+
debug: function () {
|
|
1335
|
+
var _a;
|
|
1336
|
+
var args = [];
|
|
1337
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
1338
|
+
args[_i] = arguments[_i];
|
|
1339
|
+
}
|
|
1340
|
+
if (!_this.config.debug) {
|
|
1341
|
+
return;
|
|
1342
|
+
}
|
|
1343
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1344
|
+
var func = (_a = console.debug.__hb_original) !== null && _a !== void 0 ? _a : console.debug;
|
|
1345
|
+
return func.apply(void 0, args);
|
|
1346
|
+
},
|
|
1347
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1348
|
+
warn: (_c = console.warn.__hb_original) !== null && _c !== void 0 ? _c : console.warn,
|
|
1349
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1350
|
+
error: (_d = console.error.__hb_original) !== null && _d !== void 0 ? _d : console.error,
|
|
1351
|
+
};
|
|
1352
|
+
};
|
|
1353
|
+
return ThrottledEventsWorker;
|
|
1354
|
+
}());
|
|
1355
|
+
throttled_events_worker.ThrottledEventsWorker = ThrottledEventsWorker;
|
|
1356
|
+
|
|
1357
|
+
var __assign = (commonjsGlobal && commonjsGlobal.__assign) || function () {
|
|
1358
|
+
__assign = Object.assign || function(t) {
|
|
1359
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
1360
|
+
s = arguments[i];
|
|
1361
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
1362
|
+
t[p] = s[p];
|
|
1363
|
+
}
|
|
1364
|
+
return t;
|
|
1365
|
+
};
|
|
1366
|
+
return __assign.apply(this, arguments);
|
|
1367
|
+
};
|
|
1368
|
+
var __awaiter = (commonjsGlobal && commonjsGlobal.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
1369
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
1370
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
1371
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
1372
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
1373
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
1374
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
1375
|
+
});
|
|
1376
|
+
};
|
|
1377
|
+
var __generator = (commonjsGlobal && commonjsGlobal.__generator) || function (thisArg, body) {
|
|
1378
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
1379
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
1380
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
1381
|
+
function step(op) {
|
|
1382
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
1383
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
1384
|
+
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;
|
|
1385
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
1386
|
+
switch (op[0]) {
|
|
1387
|
+
case 0: case 1: t = op; break;
|
|
1388
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
1389
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
1390
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
1391
|
+
default:
|
|
1392
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
1393
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
1394
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
1395
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
1396
|
+
if (t[2]) _.ops.pop();
|
|
1397
|
+
_.trys.pop(); continue;
|
|
1398
|
+
}
|
|
1399
|
+
op = body.call(thisArg, _);
|
|
1400
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
1401
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
1402
|
+
}
|
|
1403
|
+
};
|
|
1404
|
+
Object.defineProperty(client, "__esModule", { value: true });
|
|
1405
|
+
client.Client = void 0;
|
|
1406
|
+
var util_1 = util;
|
|
1407
|
+
var store_1 = store;
|
|
1408
|
+
var throttled_events_worker_1 = throttled_events_worker;
|
|
1409
|
+
var defaults_1 = defaults;
|
|
1410
|
+
// Split at commas and spaces
|
|
1411
|
+
var TAG_SEPARATOR = /,|\s+/;
|
|
1412
|
+
// Checks for non-blank characters
|
|
1413
|
+
var NOT_BLANK = /\S/;
|
|
1414
|
+
var Client = /** @class */ (function () {
|
|
1415
|
+
function Client(opts, transport) {
|
|
1416
|
+
if (opts === void 0) { opts = {}; }
|
|
1417
|
+
this.__pluginsLoaded = false;
|
|
1418
|
+
this.__store = null;
|
|
1419
|
+
this.__beforeNotifyHandlers = [];
|
|
1420
|
+
this.__beforeEventHandlers = [];
|
|
1421
|
+
this.__afterNotifyHandlers = [];
|
|
1422
|
+
this.__pendingEvents = new Set();
|
|
1423
|
+
this.__notifier = {
|
|
1424
|
+
name: '@honeybadger-io/core',
|
|
1425
|
+
url: 'https://github.com/honeybadger-io/honeybadger-js/tree/master/packages/core',
|
|
1426
|
+
version: '6.16.0'
|
|
1427
|
+
};
|
|
1428
|
+
this.config = __assign(__assign({}, defaults_1.CONFIG), opts);
|
|
1429
|
+
this.__initStore();
|
|
1430
|
+
this.__transport = transport;
|
|
1431
|
+
this.__eventsWorker = new throttled_events_worker_1.ThrottledEventsWorker(this.config, this.__transport);
|
|
1432
|
+
this.logger = (0, util_1.logger)(this);
|
|
1433
|
+
this.__applyEventsEnabledShim(opts);
|
|
1434
|
+
}
|
|
1435
|
+
Client.prototype.getVersion = function () {
|
|
1436
|
+
return this.__notifier.version;
|
|
1437
|
+
};
|
|
1438
|
+
Client.prototype.getNotifier = function () {
|
|
1439
|
+
return this.__notifier;
|
|
1440
|
+
};
|
|
1441
|
+
/**
|
|
1442
|
+
* CAREFUL: When adding a new notifier or updating the name of an existing notifier,
|
|
1443
|
+
* the Honeybadger rails project may need its mappings updated.
|
|
1444
|
+
* See https://github.com/honeybadger-io/honeybadger/blob/master/app/presenters/breadcrumbs_presenter.rb
|
|
1445
|
+
* https://github.com/honeybadger-io/honeybadger/blob/master/app/models/parser/java_script.rb
|
|
1446
|
+
* https://github.com/honeybadger-io/honeybadger/blob/master/app/models/language.rb
|
|
1447
|
+
**/
|
|
1448
|
+
Client.prototype.setNotifier = function (notifier) {
|
|
1449
|
+
this.__notifier = notifier;
|
|
1450
|
+
};
|
|
1451
|
+
Client.prototype.configure = function (opts) {
|
|
1452
|
+
if (opts === void 0) { opts = {}; }
|
|
1453
|
+
for (var k in opts) {
|
|
1454
|
+
this.config[k] = opts[k];
|
|
1455
|
+
}
|
|
1456
|
+
this.__applyEventsEnabledShim(opts);
|
|
1457
|
+
this.__eventsWorker.configure(this.config);
|
|
1458
|
+
this.loadPlugins();
|
|
1459
|
+
return this;
|
|
1460
|
+
};
|
|
1461
|
+
/**
|
|
1462
|
+
* Backwards compatibility: `eventsEnabled: true` used to opt into console events.
|
|
1463
|
+
* The deprecated flag auto-enables `insights.enabled` and `insights.console`;
|
|
1464
|
+
* explicit user-provided insights values win over the shim.
|
|
1465
|
+
*/
|
|
1466
|
+
Client.prototype.__applyEventsEnabledShim = function (opts) {
|
|
1467
|
+
var _a;
|
|
1468
|
+
if (opts.eventsEnabled !== true) {
|
|
1469
|
+
return;
|
|
1470
|
+
}
|
|
1471
|
+
this.logger.warn('Deprecation warning: `eventsEnabled` has been deprecated; please use `insights.enabled` and `insights.console` instead.');
|
|
1472
|
+
this.config.insights = __assign(__assign(__assign({}, ((_a = this.config.insights) !== null && _a !== void 0 ? _a : {})), { enabled: true, console: true }), opts.insights);
|
|
1473
|
+
};
|
|
1474
|
+
Client.prototype.loadPlugins = function () {
|
|
1475
|
+
var _this = this;
|
|
1476
|
+
var pluginsToLoad = this.__pluginsLoaded
|
|
1477
|
+
? this.config.__plugins.filter(function (plugin) { return plugin.shouldReloadOnConfigure; })
|
|
1478
|
+
: this.config.__plugins;
|
|
1479
|
+
pluginsToLoad.forEach(function (plugin) { return plugin.load(_this); });
|
|
1480
|
+
this.__pluginsLoaded = true;
|
|
1481
|
+
};
|
|
1482
|
+
Client.prototype.__initStore = function () {
|
|
1483
|
+
this.__store = new store_1.GlobalStore({ context: {}, eventContext: {}, breadcrumbs: [] }, this.config.maxBreadcrumbs);
|
|
1484
|
+
};
|
|
1485
|
+
Client.prototype.beforeNotify = function (handler) {
|
|
1486
|
+
this.__beforeNotifyHandlers.push(handler);
|
|
1487
|
+
return this;
|
|
1488
|
+
};
|
|
1489
|
+
Client.prototype.beforeEvent = function (handler) {
|
|
1490
|
+
this.__beforeEventHandlers.push(handler);
|
|
1491
|
+
return this;
|
|
1492
|
+
};
|
|
1493
|
+
Client.prototype.afterNotify = function (handler) {
|
|
1494
|
+
this.__afterNotifyHandlers.push(handler);
|
|
1495
|
+
return this;
|
|
1496
|
+
};
|
|
1497
|
+
Client.prototype.setContext = function (context) {
|
|
1498
|
+
if (typeof context === 'object' && context != null) {
|
|
1499
|
+
this.__store.setContext(context);
|
|
1500
|
+
}
|
|
1501
|
+
return this;
|
|
1502
|
+
};
|
|
1503
|
+
Client.prototype.setEventContext = function (eventContext) {
|
|
1504
|
+
if (typeof eventContext === 'object' && eventContext != null) {
|
|
1505
|
+
this.__store.setEventContext(eventContext);
|
|
1506
|
+
}
|
|
1507
|
+
return this;
|
|
1508
|
+
};
|
|
1509
|
+
Client.prototype.clearEventContext = function () {
|
|
1510
|
+
this.__store.clearEventContext();
|
|
1511
|
+
return this;
|
|
1512
|
+
};
|
|
1513
|
+
Client.prototype.resetContext = function (context) {
|
|
1514
|
+
this.logger.warn('Deprecation warning: `Honeybadger.resetContext()` has been deprecated; please use `Honeybadger.clear()` instead.');
|
|
1515
|
+
this.__store.clear();
|
|
1516
|
+
if (typeof context === 'object' && context !== null) {
|
|
1517
|
+
this.__store.setContext(context);
|
|
1518
|
+
}
|
|
1519
|
+
return this;
|
|
1520
|
+
};
|
|
1521
|
+
Client.prototype.clear = function () {
|
|
1522
|
+
this.__store.clear();
|
|
1523
|
+
return this;
|
|
1524
|
+
};
|
|
1525
|
+
Client.prototype.notify = function (noticeable, name, extra) {
|
|
1526
|
+
var _this = this;
|
|
1527
|
+
if (name === void 0) { name = undefined; }
|
|
1528
|
+
if (extra === void 0) { extra = undefined; }
|
|
1529
|
+
var notice = this.makeNotice(noticeable, name, extra);
|
|
1530
|
+
// we need to have the source file data before the beforeNotifyHandlers,
|
|
1531
|
+
// in case they modify them
|
|
1532
|
+
var sourceCodeData = notice && notice.backtrace ? notice.backtrace.map(function (trace) { return (0, util_1.shallowClone)(trace); }) : null;
|
|
1533
|
+
var preConditionsResult = this.__runPreconditions(notice);
|
|
1534
|
+
if (preConditionsResult instanceof Error) {
|
|
1535
|
+
(0, util_1.runAfterNotifyHandlers)(notice, this.__afterNotifyHandlers, preConditionsResult);
|
|
1536
|
+
return false;
|
|
1537
|
+
}
|
|
1538
|
+
if (preConditionsResult instanceof Promise) {
|
|
1539
|
+
preConditionsResult.then(function (result) {
|
|
1540
|
+
if (result instanceof Error) {
|
|
1541
|
+
(0, util_1.runAfterNotifyHandlers)(notice, _this.__afterNotifyHandlers, result);
|
|
1542
|
+
return false;
|
|
1543
|
+
}
|
|
1544
|
+
return _this.__send(notice, sourceCodeData);
|
|
1545
|
+
});
|
|
1546
|
+
return true;
|
|
1547
|
+
}
|
|
1548
|
+
this.__send(notice, sourceCodeData).catch(function (_err) { });
|
|
1549
|
+
return true;
|
|
1550
|
+
};
|
|
1551
|
+
/**
|
|
1552
|
+
* An async version of {@link notify} that resolves only after the notice has been reported to Honeybadger.
|
|
1553
|
+
* Implemented using the {@link afterNotify} hook.
|
|
1554
|
+
* Rejects if for any reason the report failed to be reported.
|
|
1555
|
+
* Useful in serverless environments (AWS Lambda).
|
|
1556
|
+
*/
|
|
1557
|
+
Client.prototype.notifyAsync = function (noticeable, name, extra) {
|
|
1558
|
+
var _this = this;
|
|
1559
|
+
if (name === void 0) { name = undefined; }
|
|
1560
|
+
if (extra === void 0) { extra = undefined; }
|
|
1561
|
+
return new Promise(function (resolve, reject) {
|
|
1562
|
+
var applyAfterNotify = function (partialNotice) {
|
|
1563
|
+
var originalAfterNotify = partialNotice.afterNotify;
|
|
1564
|
+
partialNotice.afterNotify = function (err) {
|
|
1565
|
+
originalAfterNotify === null || originalAfterNotify === void 0 ? void 0 : originalAfterNotify.call(_this, err);
|
|
1566
|
+
if (err) {
|
|
1567
|
+
return reject(err);
|
|
1568
|
+
}
|
|
1569
|
+
resolve();
|
|
1570
|
+
};
|
|
1571
|
+
};
|
|
1572
|
+
// We have to respect any afterNotify hooks that come from the arguments
|
|
1573
|
+
var objectToOverride;
|
|
1574
|
+
if (noticeable.afterNotify) {
|
|
1575
|
+
objectToOverride = noticeable;
|
|
1576
|
+
}
|
|
1577
|
+
else if (name && name.afterNotify) {
|
|
1578
|
+
objectToOverride = name;
|
|
1579
|
+
}
|
|
1580
|
+
else if (extra && extra.afterNotify) {
|
|
1581
|
+
objectToOverride = extra;
|
|
1582
|
+
}
|
|
1583
|
+
else if (name && typeof name === 'object') {
|
|
1584
|
+
objectToOverride = name;
|
|
1585
|
+
}
|
|
1586
|
+
else if (extra) {
|
|
1587
|
+
objectToOverride = extra;
|
|
1588
|
+
}
|
|
1589
|
+
else {
|
|
1590
|
+
objectToOverride = name = {};
|
|
1591
|
+
}
|
|
1592
|
+
applyAfterNotify(objectToOverride);
|
|
1593
|
+
_this.notify(noticeable, name, extra);
|
|
1594
|
+
});
|
|
1595
|
+
};
|
|
1596
|
+
Client.prototype.makeNotice = function (noticeable, name, extra) {
|
|
1597
|
+
if (name === void 0) { name = undefined; }
|
|
1598
|
+
if (extra === void 0) { extra = undefined; }
|
|
1599
|
+
var notice = (0, util_1.makeNotice)(noticeable);
|
|
1600
|
+
if (name && !(typeof name === 'object')) {
|
|
1601
|
+
var n = String(name);
|
|
1602
|
+
name = { name: n };
|
|
1603
|
+
}
|
|
1604
|
+
if (name) {
|
|
1605
|
+
notice = (0, util_1.mergeNotice)(notice, name);
|
|
1606
|
+
}
|
|
1607
|
+
if (typeof extra === 'object' && extra !== null) {
|
|
1608
|
+
notice = (0, util_1.mergeNotice)(notice, extra);
|
|
1609
|
+
}
|
|
1610
|
+
if ((0, util_1.objectIsEmpty)(notice)) {
|
|
1611
|
+
return null;
|
|
1612
|
+
}
|
|
1613
|
+
var context = this.__store.getContents('context');
|
|
1614
|
+
var noticeTags = this.__constructTags(notice.tags);
|
|
1615
|
+
var contextTags = this.__constructTags(context['tags']);
|
|
1616
|
+
var configTags = this.__constructTags(this.config.tags);
|
|
1617
|
+
// Turning into a Set will remove duplicates
|
|
1618
|
+
var tags = noticeTags.concat(contextTags).concat(configTags);
|
|
1619
|
+
var uniqueTags = tags.filter(function (item, index) { return tags.indexOf(item) === index; });
|
|
1620
|
+
notice = (0, util_1.merge)(notice, {
|
|
1621
|
+
name: notice.name || 'Error',
|
|
1622
|
+
context: (0, util_1.merge)(context, notice.context),
|
|
1623
|
+
projectRoot: notice.projectRoot || this.config.projectRoot,
|
|
1624
|
+
environment: notice.environment || this.config.environment,
|
|
1625
|
+
component: notice.component || this.config.component,
|
|
1626
|
+
action: notice.action || this.config.action,
|
|
1627
|
+
revision: notice.revision || this.config.revision,
|
|
1628
|
+
tags: uniqueTags,
|
|
1629
|
+
});
|
|
1630
|
+
// If we're passed a custom backtrace array, use it
|
|
1631
|
+
// Otherwise we make one.
|
|
1632
|
+
if (!Array.isArray(notice.backtrace) || !notice.backtrace.length) {
|
|
1633
|
+
if (typeof notice.stack !== 'string' || !notice.stack.trim()) {
|
|
1634
|
+
notice.stack = (0, util_1.generateStackTrace)();
|
|
1635
|
+
notice.backtrace = (0, util_1.makeBacktrace)(notice.stack, true, this.logger);
|
|
1636
|
+
}
|
|
1637
|
+
else {
|
|
1638
|
+
notice.backtrace = (0, util_1.makeBacktrace)(notice.stack, false, this.logger);
|
|
1639
|
+
}
|
|
1640
|
+
}
|
|
1641
|
+
return notice;
|
|
1642
|
+
};
|
|
1643
|
+
Client.prototype.addBreadcrumb = function (message, opts) {
|
|
1644
|
+
if (!this.config.breadcrumbsEnabled) {
|
|
1645
|
+
return;
|
|
1646
|
+
}
|
|
1647
|
+
opts = opts || {};
|
|
1648
|
+
var metadata = (0, util_1.shallowClone)(opts.metadata);
|
|
1649
|
+
var category = opts.category || 'custom';
|
|
1650
|
+
var timestamp = new Date().toISOString();
|
|
1651
|
+
this.__store.addBreadcrumb({
|
|
1652
|
+
category: category,
|
|
1653
|
+
message: message,
|
|
1654
|
+
metadata: metadata,
|
|
1655
|
+
timestamp: timestamp
|
|
1656
|
+
});
|
|
1657
|
+
return this;
|
|
1658
|
+
};
|
|
1659
|
+
/**
|
|
1660
|
+
* @deprecated Use {@link event} instead.
|
|
1661
|
+
*/
|
|
1662
|
+
Client.prototype.logEvent = function (data) {
|
|
1663
|
+
(0, util_1.logDeprecatedMethod)(this.logger, 'Honeybadger.logEvent', 'Honeybadger.event');
|
|
1664
|
+
this.event('log', data);
|
|
1665
|
+
};
|
|
1666
|
+
Client.prototype.event = function (type, data) {
|
|
1667
|
+
var _this = this;
|
|
1668
|
+
var _a;
|
|
1669
|
+
if (typeof type === 'object') {
|
|
1670
|
+
data = type;
|
|
1671
|
+
type = (_a = type['event_type']) !== null && _a !== void 0 ? _a : undefined;
|
|
1672
|
+
}
|
|
1673
|
+
var eventContext = this.__store.getContents('eventContext') || {};
|
|
1674
|
+
var payload = __assign(__assign({ event_type: type, ts: new Date().toISOString() }, eventContext), data);
|
|
1675
|
+
// Track in-flight handler chains so flushAsync() can await them before
|
|
1676
|
+
// delegating to the events logger; otherwise a caller that awaits flushAsync()
|
|
1677
|
+
// immediately after event() may flush before the payload enters the queue.
|
|
1678
|
+
var inFlight = (0, util_1.runBeforeEventHandlers)(payload, this.__beforeEventHandlers, this.logger)
|
|
1679
|
+
.then(function (shouldSend) {
|
|
1680
|
+
var _a, _b;
|
|
1681
|
+
if (!shouldSend) {
|
|
1682
|
+
_this.logger.debug('skipping event: beforeEvent handler returned false');
|
|
1683
|
+
return;
|
|
1684
|
+
}
|
|
1685
|
+
var sampleRate = (_b = (_a = _this.config.events) === null || _a === void 0 ? void 0 : _a.sampleRatePercentage) !== null && _b !== void 0 ? _b : 100;
|
|
1686
|
+
if (!(0, util_1.shouldSampleEvent)(payload, sampleRate)) {
|
|
1687
|
+
_this.logger.debug('skipping event: dropped by sampleRatePercentage');
|
|
1688
|
+
return;
|
|
1689
|
+
}
|
|
1690
|
+
delete payload._hb;
|
|
1691
|
+
_this.__eventsWorker.log(payload);
|
|
1692
|
+
})
|
|
1693
|
+
.catch(function (err) {
|
|
1694
|
+
// should not happen, because each handler is wrapped with a try/catch
|
|
1695
|
+
_this.logger.error('beforeEvent handler chain failed; dropping event', err);
|
|
1696
|
+
})
|
|
1697
|
+
.finally(function () {
|
|
1698
|
+
_this.__pendingEvents.delete(inFlight);
|
|
1699
|
+
});
|
|
1700
|
+
this.__pendingEvents.add(inFlight);
|
|
1701
|
+
};
|
|
1702
|
+
/**
|
|
1703
|
+
* This method currently flushes the event (Insights) queue.
|
|
1704
|
+
* In the future, it should also flush the error queue (assuming an error throttler is implemented).
|
|
1705
|
+
*/
|
|
1706
|
+
Client.prototype.flushAsync = function () {
|
|
1707
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
1708
|
+
return __generator(this, function (_a) {
|
|
1709
|
+
switch (_a.label) {
|
|
1710
|
+
case 0:
|
|
1711
|
+
if (!(this.__pendingEvents.size > 0)) return [3 /*break*/, 2];
|
|
1712
|
+
return [4 /*yield*/, Promise.allSettled(Array.from(this.__pendingEvents))];
|
|
1713
|
+
case 1:
|
|
1714
|
+
_a.sent();
|
|
1715
|
+
_a.label = 2;
|
|
1716
|
+
case 2: return [2 /*return*/, this.__eventsWorker.flushAsync()];
|
|
1717
|
+
}
|
|
1718
|
+
});
|
|
1719
|
+
});
|
|
1720
|
+
};
|
|
1721
|
+
Client.prototype.__getBreadcrumbs = function () {
|
|
1722
|
+
return this.__store.getContents('breadcrumbs').slice();
|
|
1723
|
+
};
|
|
1724
|
+
Client.prototype.__getContext = function () {
|
|
1725
|
+
return this.__store.getContents('context');
|
|
1726
|
+
};
|
|
1727
|
+
Client.prototype.__developmentMode = function () {
|
|
1728
|
+
if (this.config.reportData === true) {
|
|
1729
|
+
return false;
|
|
1730
|
+
}
|
|
1731
|
+
return (this.config.environment && this.config.developmentEnvironments.includes(this.config.environment));
|
|
1732
|
+
};
|
|
1733
|
+
Client.prototype.__buildPayload = function (notice) {
|
|
1734
|
+
var headers = (0, util_1.filter)(notice.headers, this.config.filters) || {};
|
|
1735
|
+
var cgiData = (0, util_1.filter)(__assign(__assign({}, notice.cgiData), (0, util_1.formatCGIData)(headers, 'HTTP_')), this.config.filters);
|
|
1736
|
+
return {
|
|
1737
|
+
notifier: this.__notifier,
|
|
1738
|
+
breadcrumbs: {
|
|
1739
|
+
enabled: !!this.config.breadcrumbsEnabled,
|
|
1740
|
+
trail: notice.__breadcrumbs || []
|
|
1741
|
+
},
|
|
1742
|
+
error: {
|
|
1743
|
+
class: notice.name,
|
|
1744
|
+
message: notice.message,
|
|
1745
|
+
backtrace: notice.backtrace,
|
|
1746
|
+
fingerprint: notice.fingerprint,
|
|
1747
|
+
tags: notice.tags,
|
|
1748
|
+
causes: (0, util_1.getCauses)(notice, this.logger),
|
|
1749
|
+
},
|
|
1750
|
+
request: {
|
|
1751
|
+
url: (0, util_1.filterUrl)(notice.url, this.config.filters),
|
|
1752
|
+
component: notice.component,
|
|
1753
|
+
action: notice.action,
|
|
1754
|
+
context: notice.context,
|
|
1755
|
+
cgi_data: cgiData,
|
|
1756
|
+
params: (0, util_1.filter)(notice.params, this.config.filters) || {},
|
|
1757
|
+
session: (0, util_1.filter)(notice.session, this.config.filters) || {}
|
|
1758
|
+
},
|
|
1759
|
+
server: {
|
|
1760
|
+
project_root: notice.projectRoot,
|
|
1761
|
+
environment_name: notice.environment,
|
|
1762
|
+
revision: notice.revision,
|
|
1763
|
+
hostname: this.config.hostname,
|
|
1764
|
+
time: new Date().toUTCString()
|
|
1765
|
+
},
|
|
1766
|
+
details: notice.details || {}
|
|
1767
|
+
};
|
|
1768
|
+
};
|
|
1769
|
+
Client.prototype.__constructTags = function (tags) {
|
|
1770
|
+
if (!tags) {
|
|
1771
|
+
return [];
|
|
1772
|
+
}
|
|
1773
|
+
return tags.toString().split(TAG_SEPARATOR).filter(function (tag) { return NOT_BLANK.test(tag); });
|
|
1774
|
+
};
|
|
1775
|
+
Client.prototype.__runPreconditions = function (notice) {
|
|
1776
|
+
var _this = this;
|
|
1777
|
+
var preConditionError = null;
|
|
1778
|
+
if (!notice) {
|
|
1779
|
+
this.logger.debug('failed to build error report');
|
|
1780
|
+
preConditionError = new Error('failed to build error report');
|
|
1781
|
+
}
|
|
1782
|
+
if (this.config.reportData === false) {
|
|
1783
|
+
this.logger.debug('skipping error report: honeybadger.js is disabled', notice);
|
|
1784
|
+
preConditionError = new Error('honeybadger.js is disabled');
|
|
1785
|
+
}
|
|
1786
|
+
if (this.__developmentMode()) {
|
|
1787
|
+
this.logger.log('honeybadger.js is in development mode; the following error report will be sent in production.', notice);
|
|
1788
|
+
preConditionError = new Error('honeybadger.js is in development mode');
|
|
1789
|
+
}
|
|
1790
|
+
if (!this.config.apiKey) {
|
|
1791
|
+
this.logger.warn('could not send error report: no API key has been configured', notice);
|
|
1792
|
+
preConditionError = new Error('missing API key');
|
|
1793
|
+
}
|
|
1794
|
+
var beforeNotifyResult = (0, util_1.runBeforeNotifyHandlers)(notice, this.__beforeNotifyHandlers);
|
|
1795
|
+
if (!preConditionError && !beforeNotifyResult.result) {
|
|
1796
|
+
this.logger.debug('skipping error report: one or more beforeNotify handlers returned false', notice);
|
|
1797
|
+
preConditionError = new Error('beforeNotify handlers returned false');
|
|
1798
|
+
}
|
|
1799
|
+
if (beforeNotifyResult.results.length && beforeNotifyResult.results.some(function (result) { return result instanceof Promise; })) {
|
|
1800
|
+
return Promise.allSettled(beforeNotifyResult.results)
|
|
1801
|
+
.then(function (results) {
|
|
1802
|
+
if (!preConditionError && (results.some(function (result) { return result.status === 'rejected' || result.value === false; }))) {
|
|
1803
|
+
_this.logger.debug('skipping error report: one or more beforeNotify handlers returned false', notice);
|
|
1804
|
+
preConditionError = new Error('beforeNotify handlers (async) returned false');
|
|
1805
|
+
}
|
|
1806
|
+
if (preConditionError) {
|
|
1807
|
+
return preConditionError;
|
|
1808
|
+
}
|
|
1809
|
+
});
|
|
1810
|
+
}
|
|
1811
|
+
return preConditionError;
|
|
1812
|
+
};
|
|
1813
|
+
Client.prototype.__send = function (notice, originalBacktrace) {
|
|
1814
|
+
var _this = this;
|
|
1815
|
+
if (this.config.breadcrumbsEnabled) {
|
|
1816
|
+
this.addBreadcrumb('Honeybadger Notice', {
|
|
1817
|
+
category: 'notice',
|
|
1818
|
+
metadata: {
|
|
1819
|
+
message: notice.message,
|
|
1820
|
+
name: notice.name,
|
|
1821
|
+
stack: notice.stack
|
|
1822
|
+
}
|
|
1823
|
+
});
|
|
1824
|
+
notice.__breadcrumbs = this.__store.getContents('breadcrumbs');
|
|
1825
|
+
}
|
|
1826
|
+
else {
|
|
1827
|
+
notice.__breadcrumbs = [];
|
|
1828
|
+
}
|
|
1829
|
+
return (0, util_1.getSourceForBacktrace)(originalBacktrace, this.__getSourceFileHandler)
|
|
1830
|
+
.then(function (sourcePerTrace) { return __awaiter(_this, void 0, void 0, function () {
|
|
1831
|
+
var payload;
|
|
1832
|
+
return __generator(this, function (_a) {
|
|
1833
|
+
sourcePerTrace.forEach(function (source, index) {
|
|
1834
|
+
notice.backtrace[index].source = source;
|
|
1835
|
+
});
|
|
1836
|
+
payload = this.__buildPayload(notice);
|
|
1837
|
+
return [2 /*return*/, this.__transport
|
|
1838
|
+
.send({
|
|
1839
|
+
headers: {
|
|
1840
|
+
'X-API-Key': this.config.apiKey,
|
|
1841
|
+
'Content-Type': 'application/json',
|
|
1842
|
+
'Accept': 'text/json, application/json'
|
|
1843
|
+
},
|
|
1844
|
+
method: 'POST',
|
|
1845
|
+
endpoint: (0, util_1.endpoint)(this.config.endpoint, '/v1/notices/js'),
|
|
1846
|
+
maxObjectDepth: this.config.maxObjectDepth,
|
|
1847
|
+
logger: this.logger,
|
|
1848
|
+
}, payload)];
|
|
1849
|
+
});
|
|
1850
|
+
}); })
|
|
1851
|
+
.then(function (res) {
|
|
1852
|
+
if (res.statusCode !== 201) {
|
|
1853
|
+
(0, util_1.runAfterNotifyHandlers)(notice, _this.__afterNotifyHandlers, new Error("Bad HTTP response: ".concat(res.statusCode)));
|
|
1854
|
+
_this.logger.warn("Error report failed: unknown response from server. code=".concat(res.statusCode));
|
|
1855
|
+
return false;
|
|
1856
|
+
}
|
|
1857
|
+
var uuid = JSON.parse(res.body).id;
|
|
1858
|
+
(0, util_1.runAfterNotifyHandlers)((0, util_1.merge)(notice, {
|
|
1859
|
+
id: uuid
|
|
1860
|
+
}), _this.__afterNotifyHandlers);
|
|
1861
|
+
var noticeUrl = (0, util_1.endpoint)(_this.config.appEndpoint, "notice/".concat(uuid));
|
|
1862
|
+
_this.logger.info("Error report sent \u26A1 ".concat(noticeUrl));
|
|
1863
|
+
return true;
|
|
1864
|
+
})
|
|
1865
|
+
.catch(function (err) {
|
|
1866
|
+
_this.logger.error('Error report failed: an unknown error occurred.', "message=".concat(err.message));
|
|
1867
|
+
(0, util_1.runAfterNotifyHandlers)(notice, _this.__afterNotifyHandlers, err);
|
|
1868
|
+
return false;
|
|
1869
|
+
});
|
|
1870
|
+
};
|
|
1871
|
+
return Client;
|
|
1872
|
+
}());
|
|
1873
|
+
client.Client = Client;
|
|
1874
|
+
|
|
1875
|
+
var types = {};
|
|
1876
|
+
|
|
1877
|
+
Object.defineProperty(types, "__esModule", { value: true });
|
|
1878
|
+
|
|
1879
|
+
(function (exports) {
|
|
1880
|
+
var __createBinding = (commonjsGlobal && commonjsGlobal.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
1881
|
+
if (k2 === undefined) k2 = k;
|
|
1882
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
1883
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
1884
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
1885
|
+
}
|
|
1886
|
+
Object.defineProperty(o, k2, desc);
|
|
1887
|
+
}) : (function(o, m, k, k2) {
|
|
1888
|
+
if (k2 === undefined) k2 = k;
|
|
1889
|
+
o[k2] = m[k];
|
|
1890
|
+
}));
|
|
1891
|
+
var __setModuleDefault = (commonjsGlobal && commonjsGlobal.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
1892
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
1893
|
+
}) : function(o, v) {
|
|
1894
|
+
o["default"] = v;
|
|
1895
|
+
});
|
|
1896
|
+
var __exportStar = (commonjsGlobal && commonjsGlobal.__exportStar) || function(m, exports) {
|
|
1897
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
1898
|
+
};
|
|
1899
|
+
var __importStar = (commonjsGlobal && commonjsGlobal.__importStar) || function (mod) {
|
|
1900
|
+
if (mod && mod.__esModule) return mod;
|
|
1901
|
+
var result = {};
|
|
1902
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
1903
|
+
__setModuleDefault(result, mod);
|
|
1904
|
+
return result;
|
|
1905
|
+
};
|
|
1906
|
+
var __importDefault = (commonjsGlobal && commonjsGlobal.__importDefault) || function (mod) {
|
|
1907
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
1908
|
+
};
|
|
1909
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1910
|
+
exports.Plugins = exports.Defaults = exports.Util = exports.Types = exports.Client = void 0;
|
|
1911
|
+
var console_events_1 = __importDefault(console_events);
|
|
1912
|
+
var client_1 = client;
|
|
1913
|
+
Object.defineProperty(exports, "Client", { enumerable: true, get: function () { return client_1.Client; } });
|
|
1914
|
+
__exportStar(store, exports);
|
|
1915
|
+
exports.Types = __importStar(types);
|
|
1916
|
+
exports.Util = __importStar(util);
|
|
1917
|
+
exports.Defaults = __importStar(defaults);
|
|
1918
|
+
exports.Plugins = {
|
|
1919
|
+
consoleEvents: console_events_1.default,
|
|
1920
|
+
/**
|
|
1921
|
+
* @deprecated Use `consoleEvents` instead. Kept as an alias for backwards
|
|
1922
|
+
* compatibility and will be removed in a future major version.
|
|
1923
|
+
*/
|
|
1924
|
+
events: console_events_1.default,
|
|
1925
|
+
};
|
|
1926
|
+
|
|
1927
|
+
} (src));
|
|
1928
|
+
|
|
1929
|
+
var http_event = {};
|
|
1930
|
+
|
|
1931
|
+
/**
|
|
1932
|
+
* Shared helpers for HTTP-event instrumentation.
|
|
1933
|
+
*
|
|
1934
|
+
* Used by inbound (Express, Fastify, Lambda, Next.js) and — in a later PR —
|
|
1935
|
+
* outbound (`http`, `https`, `fetch`) integrations.
|
|
1936
|
+
*/
|
|
1937
|
+
Object.defineProperty(http_event, "__esModule", { value: true });
|
|
1938
|
+
http_event.buildRequestEventPayload = http_event.durationMs = http_event.startTimer = http_event.seedRequestEventContext = http_event.getOrCreateCorrelationId = http_event.getOrCreateRequestId = void 0;
|
|
1939
|
+
var crypto_1 = require$$0__default["default"];
|
|
1940
|
+
/**
|
|
1941
|
+
* Reads a header value from a Node-style headers bag in a case-insensitive
|
|
1942
|
+
* manner. When the value is an array (e.g. `Set-Cookie`), returns the first
|
|
1943
|
+
* element. Returns `undefined` when the header is missing or empty.
|
|
1944
|
+
*/
|
|
1945
|
+
function readHeader(headers, name) {
|
|
1946
|
+
if (!headers)
|
|
1947
|
+
return undefined;
|
|
1948
|
+
var lower = name.toLowerCase();
|
|
1949
|
+
var value = headers[lower];
|
|
1950
|
+
if (value === undefined) {
|
|
1951
|
+
for (var _i = 0, _a = Object.keys(headers); _i < _a.length; _i++) {
|
|
1952
|
+
var key = _a[_i];
|
|
1953
|
+
if (key.toLowerCase() === lower) {
|
|
1954
|
+
value = headers[key];
|
|
1955
|
+
break;
|
|
1956
|
+
}
|
|
1957
|
+
}
|
|
1958
|
+
}
|
|
1959
|
+
if (Array.isArray(value))
|
|
1960
|
+
value = value[0];
|
|
1961
|
+
if (typeof value !== 'string')
|
|
1962
|
+
return undefined;
|
|
1963
|
+
var trimmed = value.trim();
|
|
1964
|
+
return trimmed.length ? trimmed : undefined;
|
|
1965
|
+
}
|
|
1966
|
+
/**
|
|
1967
|
+
* Generates a UUID-like identifier. Prefers Node's `crypto.randomUUID()` when
|
|
1968
|
+
* available (Node 14.17+); falls back to a Math.random-based v4-shaped string
|
|
1969
|
+
* for older Node versions.
|
|
1970
|
+
*/
|
|
1971
|
+
function generateId() {
|
|
1972
|
+
if (typeof crypto_1.randomUUID === 'function') {
|
|
1973
|
+
try {
|
|
1974
|
+
return (0, crypto_1.randomUUID)();
|
|
1975
|
+
}
|
|
1976
|
+
catch (_e) {
|
|
1977
|
+
// fall through to manual generation
|
|
1978
|
+
}
|
|
1979
|
+
}
|
|
1980
|
+
// v4-shaped, not crypto-quality. Acceptable since this is a correlation id,
|
|
1981
|
+
// not a security token.
|
|
1982
|
+
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (ch) {
|
|
1983
|
+
var r = (Math.random() * 16) | 0;
|
|
1984
|
+
var v = ch === 'x' ? r : (r & 0x3) | 0x8;
|
|
1985
|
+
return v.toString(16);
|
|
1986
|
+
});
|
|
1987
|
+
}
|
|
1988
|
+
/**
|
|
1989
|
+
* Returns a unique-per-request id. Reads `x-request-id`, then `request-id`
|
|
1990
|
+
* headers; falls back to a generated id when neither is present.
|
|
1991
|
+
*/
|
|
1992
|
+
function getOrCreateRequestId(headers) {
|
|
1993
|
+
var _a, _b;
|
|
1994
|
+
return ((_b = (_a = readHeader(headers, 'x-request-id')) !== null && _a !== void 0 ? _a : readHeader(headers, 'request-id')) !== null && _b !== void 0 ? _b : generateId());
|
|
1995
|
+
}
|
|
1996
|
+
http_event.getOrCreateRequestId = getOrCreateRequestId;
|
|
1997
|
+
/**
|
|
1998
|
+
* Returns a correlation id that may span multiple requests in a logical trace.
|
|
1999
|
+
* Reads `x-correlation-id`, then `x-amzn-trace-id`; falls back to the supplied
|
|
2000
|
+
* `requestId` so callers always have both fields populated.
|
|
2001
|
+
*/
|
|
2002
|
+
function getOrCreateCorrelationId(headers, requestId) {
|
|
2003
|
+
var _a, _b;
|
|
2004
|
+
return ((_b = (_a = readHeader(headers, 'x-correlation-id')) !== null && _a !== void 0 ? _a : readHeader(headers, 'x-amzn-trace-id')) !== null && _b !== void 0 ? _b : requestId);
|
|
2005
|
+
}
|
|
2006
|
+
http_event.getOrCreateCorrelationId = getOrCreateCorrelationId;
|
|
2007
|
+
/**
|
|
2008
|
+
* Convenience helper for framework integrations: read request/correlation ids
|
|
2009
|
+
* from the request headers and return both. When no headers contain either
|
|
2010
|
+
* value, both ids are generated and `requestId === correlationId`.
|
|
2011
|
+
*/
|
|
2012
|
+
function seedRequestEventContext(headers) {
|
|
2013
|
+
var requestId = getOrCreateRequestId(headers);
|
|
2014
|
+
var correlationId = getOrCreateCorrelationId(headers, requestId);
|
|
2015
|
+
return { request_id: requestId, correlation_id: correlationId };
|
|
2016
|
+
}
|
|
2017
|
+
http_event.seedRequestEventContext = seedRequestEventContext;
|
|
2018
|
+
/**
|
|
2019
|
+
* Starts a high-resolution timer.
|
|
2020
|
+
*/
|
|
2021
|
+
function startTimer() {
|
|
2022
|
+
return process.hrtime.bigint();
|
|
2023
|
+
}
|
|
2024
|
+
http_event.startTimer = startTimer;
|
|
2025
|
+
var NS_PER_MS = BigInt(1000000);
|
|
2026
|
+
/**
|
|
2027
|
+
* Returns the integer number of milliseconds elapsed since `start`.
|
|
2028
|
+
*/
|
|
2029
|
+
function durationMs(start) {
|
|
2030
|
+
var diff = process.hrtime.bigint() - start;
|
|
2031
|
+
return Number(diff / NS_PER_MS);
|
|
2032
|
+
}
|
|
2033
|
+
http_event.durationMs = durationMs;
|
|
2034
|
+
/**
|
|
2035
|
+
* Builds the per-request event payload. `request_id` and `correlation_id` are
|
|
2036
|
+
* NOT added here — they live on `eventContext` and are merged onto every event
|
|
2037
|
+
* by the client.
|
|
2038
|
+
*/
|
|
2039
|
+
function buildRequestEventPayload(input) {
|
|
2040
|
+
var payload = {};
|
|
2041
|
+
if (input.method !== undefined)
|
|
2042
|
+
payload.method = input.method;
|
|
2043
|
+
if (input.path !== undefined)
|
|
2044
|
+
payload.path = input.path;
|
|
2045
|
+
if (input.route !== undefined)
|
|
2046
|
+
payload.route = input.route;
|
|
2047
|
+
if (input.status !== undefined)
|
|
2048
|
+
payload.status = input.status;
|
|
2049
|
+
if (input.duration !== undefined)
|
|
2050
|
+
payload.duration = input.duration;
|
|
2051
|
+
if (input.extra) {
|
|
2052
|
+
for (var _i = 0, _a = Object.keys(input.extra); _i < _a.length; _i++) {
|
|
2053
|
+
var k = _a[_i];
|
|
2054
|
+
if (!Object.prototype.hasOwnProperty.call(payload, k)) {
|
|
2055
|
+
payload[k] = input.extra[k];
|
|
2056
|
+
}
|
|
2057
|
+
}
|
|
2058
|
+
}
|
|
2059
|
+
return payload;
|
|
2060
|
+
}
|
|
2061
|
+
http_event.buildRequestEventPayload = buildRequestEventPayload;
|
|
2062
|
+
|
|
2063
|
+
Object.defineProperty(fastify, "__esModule", { value: true });
|
|
2064
|
+
exports.fastifyPlugin = fastify.fastifyPlugin = void 0;
|
|
2065
|
+
var core_1 = src;
|
|
2066
|
+
var http_event_1 = http_event;
|
|
2067
|
+
var kHbStart = Symbol('honeybadger.start');
|
|
2068
|
+
// `fastify-plugin` is an optional peer dependency: only Fastify users need it,
|
|
2069
|
+
// so it is resolved lazily when the factory is called (same pattern as the
|
|
2070
|
+
// `async_hooks` require in ./async_store.ts).
|
|
2071
|
+
function requireFastifyPlugin() {
|
|
2072
|
+
var _a;
|
|
2073
|
+
try {
|
|
2074
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
2075
|
+
var fp = require('fastify-plugin');
|
|
2076
|
+
return (_a = fp.default) !== null && _a !== void 0 ? _a : fp;
|
|
2077
|
+
}
|
|
2078
|
+
catch (e) {
|
|
2079
|
+
var message = typeof (e === null || e === void 0 ? void 0 : e.message) === 'string' ? e.message : '';
|
|
2080
|
+
var isMissing = (e === null || e === void 0 ? void 0 : e.code) === 'MODULE_NOT_FOUND' || (message.includes('Cannot find module') && message.includes('fastify-plugin'));
|
|
2081
|
+
if (!isMissing) {
|
|
2082
|
+
throw e;
|
|
2083
|
+
}
|
|
2084
|
+
throw new Error('@honeybadger-io/js: fastifyPlugin requires the `fastify-plugin` package. ' +
|
|
2085
|
+
'Install it in your application: npm install fastify-plugin');
|
|
2086
|
+
}
|
|
2087
|
+
}
|
|
2088
|
+
/**
|
|
2089
|
+
* Returns a Fastify plugin bound to the given Honeybadger client.
|
|
2090
|
+
*
|
|
2091
|
+
* Exposed as a factory (rather than a method on the singleton) so the
|
|
2092
|
+
* framework-specific code stays off the client API:
|
|
2093
|
+
*
|
|
2094
|
+
* const { fastifyPlugin } = require('@honeybadger-io/js/dist/server/fastify')
|
|
2095
|
+
* fastify.register(fastifyPlugin(Honeybadger))
|
|
2096
|
+
*
|
|
2097
|
+
* Requires the `fastify-plugin` package (declared as an optional peer
|
|
2098
|
+
* dependency of this package) — the factory throws with install instructions
|
|
2099
|
+
* when it cannot be resolved. The returned plugin is wrapped with
|
|
2100
|
+
* `fastify-plugin`, so its hooks apply to the calling context rather than
|
|
2101
|
+
* being encapsulated.
|
|
2102
|
+
*
|
|
2103
|
+
* The plugin runs every request inside `client.withRequest(req, ...)`, seeding
|
|
2104
|
+
* `request_id` / `correlation_id` on the event context. When
|
|
2105
|
+
* `insights.enabled` and `insights.http` are both true it also emits a
|
|
2106
|
+
* `request.handled` event per request with method, path, route, status and
|
|
2107
|
+
* duration.
|
|
2108
|
+
*
|
|
2109
|
+
* Supports Fastify 4+.
|
|
2110
|
+
*/
|
|
2111
|
+
function fastifyPlugin(client) {
|
|
2112
|
+
var fp = requireFastifyPlugin();
|
|
2113
|
+
var plugin = function (fastify, _opts, done) {
|
|
2114
|
+
fastify.addHook('onRequest', function (req, _reply, hookDone) {
|
|
2115
|
+
client.withRequest(req, function () {
|
|
2116
|
+
client.setEventContext((0, http_event_1.seedRequestEventContext)(req.headers));
|
|
2117
|
+
if (core_1.Util.resolveInsights(client.config).http) {
|
|
2118
|
+
req[kHbStart] = (0, http_event_1.startTimer)();
|
|
2119
|
+
}
|
|
2120
|
+
hookDone();
|
|
2121
|
+
});
|
|
2122
|
+
});
|
|
2123
|
+
fastify.addHook('onResponse', function (req, reply, hookDone) {
|
|
2124
|
+
// `withRequest` keys store contents off the request object, so this
|
|
2125
|
+
// re-entry shares the contents populated in `onRequest` — the event
|
|
2126
|
+
// payload below picks up `request_id` / `correlation_id` (and any
|
|
2127
|
+
// context the user set during the route handler).
|
|
2128
|
+
client.withRequest(req, function () {
|
|
2129
|
+
var _a, _b;
|
|
2130
|
+
if (core_1.Util.resolveInsights(client.config).http && req[kHbStart] != null) {
|
|
2131
|
+
client.event('request.handled', (0, http_event_1.buildRequestEventPayload)({
|
|
2132
|
+
method: req.method,
|
|
2133
|
+
path: typeof req.url === 'string' ? req.url.split('?')[0] : req.url,
|
|
2134
|
+
route: (_b = (_a = req.routeOptions) === null || _a === void 0 ? void 0 : _a.url) !== null && _b !== void 0 ? _b : req.routerPath,
|
|
2135
|
+
status: reply.statusCode,
|
|
2136
|
+
duration: (0, http_event_1.durationMs)(req[kHbStart]),
|
|
2137
|
+
}));
|
|
2138
|
+
}
|
|
2139
|
+
hookDone();
|
|
2140
|
+
});
|
|
2141
|
+
});
|
|
2142
|
+
done();
|
|
2143
|
+
};
|
|
2144
|
+
return fp(plugin, { name: '@honeybadger-io/js' });
|
|
2145
|
+
}
|
|
2146
|
+
exports.fastifyPlugin = fastify.fastifyPlugin = fastifyPlugin;
|
|
2147
|
+
|
|
2148
|
+
exports["default"] = fastify;
|
|
2149
|
+
//# sourceMappingURL=fastify.js.map
|