@multiplayer-app/session-recorder-browser 1.2.25 → 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.umd.js CHANGED
@@ -24461,7 +24461,7 @@ const DEFAULT_MAX_HTTP_CAPTURING_PAYLOAD_SIZE = 100000;
24461
24461
  const SESSION_RESPONSE = 'multiplayer-debug-session-response';
24462
24462
  const CONTINUOUS_DEBUGGING_TIMEOUT = 60000; // 1 minutes
24463
24463
  const DEBUG_SESSION_MAX_DURATION_SECONDS = 10 * 60 + 30; // TODO: move to shared config otel core
24464
- const PACKAGE_VERSION_EXPORT = "1.2.25" || 0;
24464
+ const PACKAGE_VERSION_EXPORT = "1.2.26" || 0;
24465
24465
  // Regex patterns for OpenTelemetry ignore URLs
24466
24466
  const OTEL_IGNORE_URLS = [
24467
24467
  // Traces endpoint
@@ -25319,6 +25319,9 @@ const getExporterEndpoint = (exporterEndpoint) => {
25319
25319
  /* harmony import */ var _opentelemetry_instrumentation__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @opentelemetry/instrumentation */ "../../node_modules/@opentelemetry/instrumentation/build/esm/autoLoader.js");
25320
25320
  /* 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");
25321
25321
  /* 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");
25322
+ /* harmony import */ var _opentelemetry_api__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! @opentelemetry/api */ "../../node_modules/@opentelemetry/api/build/esm/trace-api.js");
25323
+ /* harmony import */ var _opentelemetry_api__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! @opentelemetry/api */ "../../node_modules/@opentelemetry/api/build/esm/context-api.js");
25324
+ /* harmony import */ var _opentelemetry_api__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! @opentelemetry/api */ "../../node_modules/@opentelemetry/api/build/esm/trace/status.js");
25322
25325
  /* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../config */ "./src/config/index.ts");
25323
25326
  /* harmony import */ var _helpers__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./helpers */ "./src/otel/helpers.ts");
25324
25327
 
@@ -25331,10 +25334,13 @@ const getExporterEndpoint = (exporterEndpoint) => {
25331
25334
 
25332
25335
 
25333
25336
 
25337
+
25338
+
25334
25339
  class TracerBrowserSDK {
25335
25340
  constructor() {
25336
25341
  this.allowedElements = new Set(['A', 'BUTTON']);
25337
25342
  this.sessionId = '';
25343
+ this.globalErrorListenersRegistered = false;
25338
25344
  }
25339
25345
  setSessionId(sessionId, sessionType = _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionType.PLAIN) {
25340
25346
  this.sessionId = sessionId;
@@ -25473,6 +25479,7 @@ class TracerBrowserSDK {
25473
25479
  }),
25474
25480
  ],
25475
25481
  });
25482
+ this._registerGlobalErrorListeners();
25476
25483
  }
25477
25484
  start(sessionId, sessionType) {
25478
25485
  if (!this.tracerProvider) {
@@ -25492,6 +25499,39 @@ class TracerBrowserSDK {
25492
25499
  }
25493
25500
  this.exporter.setApiKey(apiKey);
25494
25501
  }
25502
+ /**
25503
+ * Capture an exception as an error span/event.
25504
+ * If there is an active span, the exception will be recorded on it.
25505
+ * Otherwise, a short-lived span will be created to hold the exception event.
25506
+ */
25507
+ captureException(error) {
25508
+ if (!error)
25509
+ return;
25510
+ // Try to record on the currently active span first
25511
+ const activeSpan = _opentelemetry_api__WEBPACK_IMPORTED_MODULE_10__.trace.getSpan(_opentelemetry_api__WEBPACK_IMPORTED_MODULE_11__.context.active());
25512
+ if (activeSpan) {
25513
+ try {
25514
+ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionRecorderSdk.captureException(error);
25515
+ return;
25516
+ }
25517
+ catch (_e) {
25518
+ // fallthrough to creating a dedicated span
25519
+ }
25520
+ }
25521
+ try {
25522
+ const tracer = _opentelemetry_api__WEBPACK_IMPORTED_MODULE_10__.trace.getTracer('session-recorder');
25523
+ const span = tracer.startSpan('exception');
25524
+ span.recordException(error);
25525
+ span.setStatus({ code: _opentelemetry_api__WEBPACK_IMPORTED_MODULE_12__.SpanStatusCode.ERROR, message: error.message });
25526
+ span.end();
25527
+ }
25528
+ catch (_err) {
25529
+ // eslint-disable-next-line no-console
25530
+ if (true) {
25531
+ console.warn('[MULTIPLAYER_SESSION_RECORDER] Failed to capture exception', _err);
25532
+ }
25533
+ }
25534
+ }
25495
25535
  _getSpanSessionIdProcessor() {
25496
25536
  return {
25497
25537
  forceFlush: () => Promise.resolve(),
@@ -25505,6 +25545,28 @@ class TracerBrowserSDK {
25505
25545
  },
25506
25546
  };
25507
25547
  }
25548
+ _registerGlobalErrorListeners() {
25549
+ if (this.globalErrorListenersRegistered)
25550
+ return;
25551
+ if (typeof window === 'undefined')
25552
+ return;
25553
+ const errorHandler = (event) => {
25554
+ const err = (event === null || event === void 0 ? void 0 : event.error) instanceof Error
25555
+ ? event.error
25556
+ : new Error((event === null || event === void 0 ? void 0 : event.message) || 'Script error');
25557
+ this.captureException(err);
25558
+ };
25559
+ const rejectionHandler = (event) => {
25560
+ const reason = (event && 'reason' in event) ? event.reason : undefined;
25561
+ const err = reason instanceof Error
25562
+ ? reason
25563
+ : new Error(typeof reason === 'string' ? reason : 'Unhandled promise rejection');
25564
+ this.captureException(err);
25565
+ };
25566
+ window.addEventListener('error', errorHandler);
25567
+ window.addEventListener('unhandledrejection', rejectionHandler);
25568
+ this.globalErrorListenersRegistered = true;
25569
+ }
25508
25570
  }
25509
25571
 
25510
25572
 
@@ -26704,6 +26766,18 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
26704
26766
  set recordingButtonClickHandler(handler) {
26705
26767
  this._sessionWidget.buttonClickExternalHandler = handler;
26706
26768
  }
26769
+ /**
26770
+ * Capture an exception manually and send it as an error trace.
26771
+ */
26772
+ captureException(error) {
26773
+ try {
26774
+ const normalizedError = this._normalizeError(error);
26775
+ this._tracer.captureException(normalizedError);
26776
+ }
26777
+ catch (e) {
26778
+ this.error = (e === null || e === void 0 ? void 0 : e.message) || 'Failed to capture exception';
26779
+ }
26780
+ }
26707
26781
  /**
26708
26782
  * @description Check if session should be started/stopped automatically
26709
26783
  * @param {ISession} [sessionPayload]
@@ -26951,6 +27025,18 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
26951
27025
  break;
26952
27026
  }
26953
27027
  }
27028
+ _normalizeError(error) {
27029
+ if (error instanceof Error)
27030
+ return error;
27031
+ if (typeof error === 'string')
27032
+ return new Error(error);
27033
+ try {
27034
+ return new Error(JSON.stringify(error));
27035
+ }
27036
+ catch (_e) {
27037
+ return new Error(String(error));
27038
+ }
27039
+ }
26954
27040
  }
26955
27041
 
26956
27042