@multiplayer-app/session-recorder-browser 1.2.24 → 1.2.26

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/index.js CHANGED
@@ -24284,7 +24284,7 @@ const DEFAULT_MAX_HTTP_CAPTURING_PAYLOAD_SIZE = 100000;
24284
24284
  const SESSION_RESPONSE = 'multiplayer-debug-session-response';
24285
24285
  const CONTINUOUS_DEBUGGING_TIMEOUT = 60000; // 1 minutes
24286
24286
  const DEBUG_SESSION_MAX_DURATION_SECONDS = 10 * 60 + 30; // TODO: move to shared config otel core
24287
- const PACKAGE_VERSION_EXPORT = "1.2.24" || 0;
24287
+ const PACKAGE_VERSION_EXPORT = "1.2.26" || 0;
24288
24288
  // Regex patterns for OpenTelemetry ignore URLs
24289
24289
  const OTEL_IGNORE_URLS = [
24290
24290
  // Traces endpoint
@@ -25130,6 +25130,9 @@ const getExporterEndpoint = (exporterEndpoint) => {
25130
25130
  /* harmony import */ var _opentelemetry_instrumentation__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @opentelemetry/instrumentation */ "../../node_modules/@opentelemetry/instrumentation/build/esm/autoLoader.js");
25131
25131
  /* harmony import */ var _opentelemetry_auto_instrumentations_web__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @opentelemetry/auto-instrumentations-web */ "../../node_modules/@opentelemetry/auto-instrumentations-web/build/esm/index.js");
25132
25132
  /* harmony import */ var _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @multiplayer-app/session-recorder-common */ "../session-recorder-common/dist/esm/index-browser.js");
25133
+ /* harmony import */ var _opentelemetry_api__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @opentelemetry/api */ "../../node_modules/@opentelemetry/api/build/esm/trace-api.js");
25134
+ /* harmony import */ var _opentelemetry_api__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @opentelemetry/api */ "../../node_modules/@opentelemetry/api/build/esm/context-api.js");
25135
+ /* harmony import */ var _opentelemetry_api__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @opentelemetry/api */ "../../node_modules/@opentelemetry/api/build/esm/trace/status.js");
25133
25136
  /* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../config */ "./src/config/index.ts");
25134
25137
  /* harmony import */ var _helpers__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./helpers */ "./src/otel/helpers.ts");
25135
25138
 
@@ -25142,10 +25145,13 @@ const getExporterEndpoint = (exporterEndpoint) => {
25142
25145
 
25143
25146
 
25144
25147
 
25148
+
25149
+
25145
25150
  class TracerBrowserSDK {
25146
25151
  constructor() {
25147
25152
  this.allowedElements = new Set(['A', 'BUTTON']);
25148
25153
  this.sessionId = '';
25154
+ this.globalErrorListenersRegistered = false;
25149
25155
  }
25150
25156
  setSessionId(sessionId, sessionType = _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionType.PLAIN) {
25151
25157
  this.sessionId = sessionId;
@@ -25284,6 +25290,7 @@ class TracerBrowserSDK {
25284
25290
  }),
25285
25291
  ],
25286
25292
  });
25293
+ this._registerGlobalErrorListeners();
25287
25294
  }
25288
25295
  start(sessionId, sessionType) {
25289
25296
  if (!this.tracerProvider) {
@@ -25303,6 +25310,39 @@ class TracerBrowserSDK {
25303
25310
  }
25304
25311
  this.exporter.setApiKey(apiKey);
25305
25312
  }
25313
+ /**
25314
+ * Capture an exception as an error span/event.
25315
+ * If there is an active span, the exception will be recorded on it.
25316
+ * Otherwise, a short-lived span will be created to hold the exception event.
25317
+ */
25318
+ captureException(error) {
25319
+ if (!error)
25320
+ return;
25321
+ // Try to record on the currently active span first
25322
+ const activeSpan = _opentelemetry_api__WEBPACK_IMPORTED_MODULE_10__.trace.getSpan(_opentelemetry_api__WEBPACK_IMPORTED_MODULE_11__.context.active());
25323
+ if (activeSpan) {
25324
+ try {
25325
+ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionRecorderSdk.captureException(error);
25326
+ return;
25327
+ }
25328
+ catch (_e) {
25329
+ // fallthrough to creating a dedicated span
25330
+ }
25331
+ }
25332
+ try {
25333
+ const tracer = _opentelemetry_api__WEBPACK_IMPORTED_MODULE_10__.trace.getTracer('session-recorder');
25334
+ const span = tracer.startSpan('exception');
25335
+ span.recordException(error);
25336
+ span.setStatus({ code: _opentelemetry_api__WEBPACK_IMPORTED_MODULE_12__.SpanStatusCode.ERROR, message: error.message });
25337
+ span.end();
25338
+ }
25339
+ catch (_err) {
25340
+ // eslint-disable-next-line no-console
25341
+ if (true) {
25342
+ console.warn('[MULTIPLAYER_SESSION_RECORDER] Failed to capture exception', _err);
25343
+ }
25344
+ }
25345
+ }
25306
25346
  _getSpanSessionIdProcessor() {
25307
25347
  return {
25308
25348
  forceFlush: () => Promise.resolve(),
@@ -25316,6 +25356,28 @@ class TracerBrowserSDK {
25316
25356
  },
25317
25357
  };
25318
25358
  }
25359
+ _registerGlobalErrorListeners() {
25360
+ if (this.globalErrorListenersRegistered)
25361
+ return;
25362
+ if (typeof window === 'undefined')
25363
+ return;
25364
+ const errorHandler = (event) => {
25365
+ const err = (event === null || event === void 0 ? void 0 : event.error) instanceof Error
25366
+ ? event.error
25367
+ : new Error((event === null || event === void 0 ? void 0 : event.message) || 'Script error');
25368
+ this.captureException(err);
25369
+ };
25370
+ const rejectionHandler = (event) => {
25371
+ const reason = (event && 'reason' in event) ? event.reason : undefined;
25372
+ const err = reason instanceof Error
25373
+ ? reason
25374
+ : new Error(typeof reason === 'string' ? reason : 'Unhandled promise rejection');
25375
+ this.captureException(err);
25376
+ };
25377
+ window.addEventListener('error', errorHandler);
25378
+ window.addEventListener('unhandledrejection', rejectionHandler);
25379
+ this.globalErrorListenersRegistered = true;
25380
+ }
25319
25381
  }
25320
25382
 
25321
25383
 
@@ -26506,6 +26568,18 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
26506
26568
  set recordingButtonClickHandler(handler) {
26507
26569
  this._sessionWidget.buttonClickExternalHandler = handler;
26508
26570
  }
26571
+ /**
26572
+ * Capture an exception manually and send it as an error trace.
26573
+ */
26574
+ captureException(error) {
26575
+ try {
26576
+ const normalizedError = this._normalizeError(error);
26577
+ this._tracer.captureException(normalizedError);
26578
+ }
26579
+ catch (e) {
26580
+ this.error = (e === null || e === void 0 ? void 0 : e.message) || 'Failed to capture exception';
26581
+ }
26582
+ }
26509
26583
  /**
26510
26584
  * @description Check if session should be started/stopped automatically
26511
26585
  * @param {ISession} [sessionPayload]
@@ -26753,6 +26827,18 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
26753
26827
  break;
26754
26828
  }
26755
26829
  }
26830
+ _normalizeError(error) {
26831
+ if (error instanceof Error)
26832
+ return error;
26833
+ if (typeof error === 'string')
26834
+ return new Error(error);
26835
+ try {
26836
+ return new Error(JSON.stringify(error));
26837
+ }
26838
+ catch (_e) {
26839
+ return new Error(String(error));
26840
+ }
26841
+ }
26756
26842
  }
26757
26843
 
26758
26844