@multiplayer-app/session-recorder-common 1.3.32 → 1.3.34
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/esm/sdk/capture-exception.d.ts +1 -0
- package/dist/esm/sdk/capture-exception.d.ts.map +1 -1
- package/dist/esm/sdk/capture-exception.js +60 -4
- package/dist/esm/sdk/capture-exception.js.map +1 -1
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/esnext/sdk/capture-exception.d.ts +1 -0
- package/dist/esnext/sdk/capture-exception.d.ts.map +1 -1
- package/dist/esnext/sdk/capture-exception.js +39 -5
- package/dist/esnext/sdk/capture-exception.js.map +1 -1
- package/dist/esnext/tsconfig.esnext.tsbuildinfo +1 -1
- package/dist/src/sdk/capture-exception.d.ts +1 -0
- package/dist/src/sdk/capture-exception.d.ts.map +1 -1
- package/dist/src/sdk/capture-exception.js +40 -5
- package/dist/src/sdk/capture-exception.js.map +1 -1
- package/package.json +1 -1
- package/src/sdk/capture-exception.ts +57 -19
|
@@ -4,4 +4,5 @@
|
|
|
4
4
|
* @returns {void}
|
|
5
5
|
*/
|
|
6
6
|
export declare const captureException: (error: Error, errorInfo?: Record<string, any>) => void;
|
|
7
|
+
export declare const shouldCaptureException: (error: Error, _errorInfo?: Record<string, any>) => boolean;
|
|
7
8
|
//# sourceMappingURL=capture-exception.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capture-exception.d.ts","sourceRoot":"","sources":["../../../src/sdk/capture-exception.ts"],"names":[],"mappings":"AAQA;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,
|
|
1
|
+
{"version":3,"file":"capture-exception.d.ts","sourceRoot":"","sources":["../../../src/sdk/capture-exception.ts"],"names":[],"mappings":"AAQA;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,GAAI,OAAO,KAAK,EAAE,YAAY,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,SA4C7E,CAAA;AAUD,eAAO,MAAM,sBAAsB,GAAI,OAAO,KAAK,EAAE,aAAa,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,KAAG,OAkCvF,CAAA"}
|
|
@@ -25,8 +25,19 @@ var __read = (this && this.__read) || function (o, n) {
|
|
|
25
25
|
}
|
|
26
26
|
return ar;
|
|
27
27
|
};
|
|
28
|
+
var __values = (this && this.__values) || function(o) {
|
|
29
|
+
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
30
|
+
if (m) return m.call(o);
|
|
31
|
+
if (o && typeof o.length === "number") return {
|
|
32
|
+
next: function () {
|
|
33
|
+
if (o && i >= o.length) o = void 0;
|
|
34
|
+
return { value: o && o[i++], done: !o };
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
38
|
+
};
|
|
28
39
|
import { context, trace, SpanStatusCode } from '@opentelemetry/api';
|
|
29
|
-
import { ATTR_EXCEPTION_MESSAGE, ATTR_EXCEPTION_STACKTRACE, ATTR_EXCEPTION_TYPE
|
|
40
|
+
import { ATTR_EXCEPTION_MESSAGE, ATTR_EXCEPTION_STACKTRACE, ATTR_EXCEPTION_TYPE } from '@opentelemetry/semantic-conventions';
|
|
30
41
|
import { getResourceAttributes } from './set-resource-attributes';
|
|
31
42
|
/**
|
|
32
43
|
* @description Add error to current span
|
|
@@ -35,7 +46,7 @@ import { getResourceAttributes } from './set-resource-attributes';
|
|
|
35
46
|
*/
|
|
36
47
|
export var captureException = function (error, errorInfo) {
|
|
37
48
|
var _a, _b;
|
|
38
|
-
if (!error) {
|
|
49
|
+
if (!error || !shouldCaptureException(error)) {
|
|
39
50
|
return;
|
|
40
51
|
}
|
|
41
52
|
var activeContext = context.active();
|
|
@@ -43,7 +54,7 @@ export var captureException = function (error, errorInfo) {
|
|
|
43
54
|
var isNewSpan = false;
|
|
44
55
|
if (!span || !span.isRecording()) {
|
|
45
56
|
span = trace.getTracer('exception').startSpan(error.name || 'Error', {
|
|
46
|
-
attributes: __assign((_a = {}, _a[ATTR_EXCEPTION_MESSAGE] = error.message, _a[ATTR_EXCEPTION_STACKTRACE] = error.stack, _a[ATTR_EXCEPTION_TYPE] = error.name, _a), getResourceAttributes())
|
|
57
|
+
attributes: __assign((_a = {}, _a[ATTR_EXCEPTION_MESSAGE] = error.message, _a[ATTR_EXCEPTION_STACKTRACE] = error.stack, _a[ATTR_EXCEPTION_TYPE] = error.name, _a), getResourceAttributes())
|
|
47
58
|
});
|
|
48
59
|
trace.setSpan(activeContext, span);
|
|
49
60
|
isNewSpan = true;
|
|
@@ -64,10 +75,55 @@ export var captureException = function (error, errorInfo) {
|
|
|
64
75
|
span.recordException(error);
|
|
65
76
|
span.setStatus({
|
|
66
77
|
code: SpanStatusCode.ERROR,
|
|
67
|
-
message: error.message
|
|
78
|
+
message: error.message
|
|
68
79
|
});
|
|
69
80
|
if (isNewSpan) {
|
|
70
81
|
span.end();
|
|
71
82
|
}
|
|
72
83
|
};
|
|
84
|
+
/**
|
|
85
|
+
* Best-effort deduplication of exceptions that fire multiple times
|
|
86
|
+
* (e.g. framework handler + global handlers) within a short time window.
|
|
87
|
+
*/
|
|
88
|
+
var exceptionDedupeWindowMs = 2000;
|
|
89
|
+
var recentExceptionFingerprints = new Map();
|
|
90
|
+
export var shouldCaptureException = function (error, _errorInfo) {
|
|
91
|
+
var e_1, _a;
|
|
92
|
+
if (!error)
|
|
93
|
+
return false;
|
|
94
|
+
var now = Date.now();
|
|
95
|
+
// Build a fingerprint that is stable enough across repeated emissions
|
|
96
|
+
// but not so broad that different errors collapse into one.
|
|
97
|
+
var keyParts = [];
|
|
98
|
+
keyParts.push(error.name || 'Error');
|
|
99
|
+
keyParts.push(error.message || '');
|
|
100
|
+
// First stack line tends to include file/line where it originated.
|
|
101
|
+
if (typeof error.stack === 'string') {
|
|
102
|
+
var firstFrame = error.stack.split('\n')[1] || '';
|
|
103
|
+
keyParts.push(firstFrame.trim());
|
|
104
|
+
}
|
|
105
|
+
var fingerprint = keyParts.join('|').slice(0, 500);
|
|
106
|
+
var lastSeen = recentExceptionFingerprints.get(fingerprint);
|
|
107
|
+
if (lastSeen && now - lastSeen < exceptionDedupeWindowMs) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
recentExceptionFingerprints.set(fingerprint, now);
|
|
111
|
+
try {
|
|
112
|
+
// Cheap cleanup of old entries to avoid unbounded growth.
|
|
113
|
+
for (var recentExceptionFingerprints_1 = __values(recentExceptionFingerprints), recentExceptionFingerprints_1_1 = recentExceptionFingerprints_1.next(); !recentExceptionFingerprints_1_1.done; recentExceptionFingerprints_1_1 = recentExceptionFingerprints_1.next()) {
|
|
114
|
+
var _b = __read(recentExceptionFingerprints_1_1.value, 2), key = _b[0], ts = _b[1];
|
|
115
|
+
if (now - ts > exceptionDedupeWindowMs * 5) {
|
|
116
|
+
recentExceptionFingerprints.delete(key);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
121
|
+
finally {
|
|
122
|
+
try {
|
|
123
|
+
if (recentExceptionFingerprints_1_1 && !recentExceptionFingerprints_1_1.done && (_a = recentExceptionFingerprints_1.return)) _a.call(recentExceptionFingerprints_1);
|
|
124
|
+
}
|
|
125
|
+
finally { if (e_1) throw e_1.error; }
|
|
126
|
+
}
|
|
127
|
+
return true;
|
|
128
|
+
};
|
|
73
129
|
//# sourceMappingURL=capture-exception.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"capture-exception.js","sourceRoot":"","sources":["../../../src/sdk/capture-exception.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"capture-exception.js","sourceRoot":"","sources":["../../../src/sdk/capture-exception.ts"],"names":[],"mappings":"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","sourcesContent":["import { context, trace, SpanStatusCode } from '@opentelemetry/api'\nimport {\n ATTR_EXCEPTION_MESSAGE,\n ATTR_EXCEPTION_STACKTRACE,\n ATTR_EXCEPTION_TYPE\n} from '@opentelemetry/semantic-conventions'\nimport { getResourceAttributes } from './set-resource-attributes'\n\n/**\n * @description Add error to current span\n * @param {Error} error\n * @returns {void}\n */\nexport const captureException = (error: Error, errorInfo?: Record<string, any>) => {\n if (!error || !shouldCaptureException(error)) {\n return\n }\n\n const activeContext = context.active()\n\n let span = trace.getSpan(activeContext)\n let isNewSpan = false\n\n if (!span || !span.isRecording()) {\n span = trace.getTracer('exception').startSpan(error.name || 'Error', {\n attributes: {\n [ATTR_EXCEPTION_MESSAGE]: error.message,\n [ATTR_EXCEPTION_STACKTRACE]: error.stack,\n [ATTR_EXCEPTION_TYPE]: error.name,\n ...getResourceAttributes()\n }\n })\n trace.setSpan(activeContext, span)\n isNewSpan = true\n } else {\n span.setAttributes({\n [ATTR_EXCEPTION_MESSAGE]: error.message,\n [ATTR_EXCEPTION_STACKTRACE]: error.stack,\n [ATTR_EXCEPTION_TYPE]: error.name\n })\n }\n\n if (errorInfo) {\n Object.entries(errorInfo).forEach(([key, value]) => {\n span.setAttribute(`error_info.${key}`, value)\n })\n }\n\n span.recordException(error)\n span.setStatus({\n code: SpanStatusCode.ERROR,\n message: error.message\n })\n\n if (isNewSpan) {\n span.end()\n }\n}\n\n/**\n * Best-effort deduplication of exceptions that fire multiple times\n * (e.g. framework handler + global handlers) within a short time window.\n */\n\nconst exceptionDedupeWindowMs = 2000\nconst recentExceptionFingerprints = new Map<string, number>()\n\nexport const shouldCaptureException = (error: Error, _errorInfo?: Record<string, any>): boolean => {\n if (!error) return false\n\n const now = Date.now()\n\n // Build a fingerprint that is stable enough across repeated emissions\n // but not so broad that different errors collapse into one.\n const keyParts: string[] = []\n keyParts.push(error.name || 'Error')\n keyParts.push(error.message || '')\n\n // First stack line tends to include file/line where it originated.\n if (typeof error.stack === 'string') {\n const firstFrame = error.stack.split('\\n')[1] || ''\n keyParts.push(firstFrame.trim())\n }\n\n const fingerprint = keyParts.join('|').slice(0, 500)\n\n const lastSeen = recentExceptionFingerprints.get(fingerprint)\n if (lastSeen && now - lastSeen < exceptionDedupeWindowMs) {\n return false\n }\n\n recentExceptionFingerprints.set(fingerprint, now)\n\n // Cheap cleanup of old entries to avoid unbounded growth.\n for (const [key, ts] of recentExceptionFingerprints) {\n if (now - ts > exceptionDedupeWindowMs * 5) {\n recentExceptionFingerprints.delete(key)\n }\n }\n\n return true\n}\n"]}
|