@multiplayer-app/session-recorder-browser 1.2.25 → 1.2.27

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.27" || 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,46 @@ 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, errorInfo) {
25508
+ if (!error)
25509
+ return;
25510
+ // Prefer attaching to the active span to keep correlation intact
25511
+ try {
25512
+ const activeSpan = _opentelemetry_api__WEBPACK_IMPORTED_MODULE_10__.trace.getSpan(_opentelemetry_api__WEBPACK_IMPORTED_MODULE_11__.context.active());
25513
+ if (activeSpan) {
25514
+ // Standard OTEL exception event + span status
25515
+ _multiplayer_app_session_recorder_common__WEBPACK_IMPORTED_MODULE_1__.SessionRecorderSdk.captureException(error);
25516
+ activeSpan.addEvent('exception', {
25517
+ 'exception.type': error.name || 'Error',
25518
+ 'exception.message': error.message,
25519
+ 'exception.stacktrace': error.stack || '',
25520
+ ...(errorInfo || {}),
25521
+ });
25522
+ return;
25523
+ }
25524
+ }
25525
+ catch (_ignored) { }
25526
+ // Fallback: create a short-lived span to hold the exception details
25527
+ try {
25528
+ const tracer = _opentelemetry_api__WEBPACK_IMPORTED_MODULE_10__.trace.getTracer('exception');
25529
+ const span = tracer.startSpan(error.name || 'Error');
25530
+ span.recordException(error);
25531
+ span.setStatus({ code: _opentelemetry_api__WEBPACK_IMPORTED_MODULE_12__.SpanStatusCode.ERROR, message: error.message });
25532
+ span.addEvent('exception', {
25533
+ 'exception.type': error.name || 'Error',
25534
+ 'exception.message': error.message,
25535
+ 'exception.stacktrace': error.stack || '',
25536
+ ...(errorInfo || {}),
25537
+ });
25538
+ span.end();
25539
+ }
25540
+ catch (_ignored) { }
25541
+ }
25495
25542
  _getSpanSessionIdProcessor() {
25496
25543
  return {
25497
25544
  forceFlush: () => Promise.resolve(),
@@ -25505,6 +25552,28 @@ class TracerBrowserSDK {
25505
25552
  },
25506
25553
  };
25507
25554
  }
25555
+ _registerGlobalErrorListeners() {
25556
+ if (this.globalErrorListenersRegistered)
25557
+ return;
25558
+ if (typeof window === 'undefined')
25559
+ return;
25560
+ const errorHandler = (event) => {
25561
+ const err = (event === null || event === void 0 ? void 0 : event.error) instanceof Error
25562
+ ? event.error
25563
+ : new Error((event === null || event === void 0 ? void 0 : event.message) || 'Script error');
25564
+ this.captureException(err);
25565
+ };
25566
+ const rejectionHandler = (event) => {
25567
+ const reason = (event && 'reason' in event) ? event.reason : undefined;
25568
+ const err = reason instanceof Error
25569
+ ? reason
25570
+ : new Error(typeof reason === 'string' ? reason : 'Unhandled promise rejection');
25571
+ this.captureException(err);
25572
+ };
25573
+ window.addEventListener('error', errorHandler);
25574
+ window.addEventListener('unhandledrejection', rejectionHandler);
25575
+ this.globalErrorListenersRegistered = true;
25576
+ }
25508
25577
  }
25509
25578
 
25510
25579
 
@@ -26704,6 +26773,19 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
26704
26773
  set recordingButtonClickHandler(handler) {
26705
26774
  this._sessionWidget.buttonClickExternalHandler = handler;
26706
26775
  }
26776
+ /**
26777
+ * Capture an exception manually and send it as an error trace.
26778
+ */
26779
+ captureException(error, errorInfo) {
26780
+ try {
26781
+ const normalizedError = this._normalizeError(error);
26782
+ const normalizedErrorInfo = this._normalizeErrorInfo(errorInfo);
26783
+ this._tracer.captureException(normalizedError, normalizedErrorInfo);
26784
+ }
26785
+ catch (e) {
26786
+ this.error = (e === null || e === void 0 ? void 0 : e.message) || 'Failed to capture exception';
26787
+ }
26788
+ }
26707
26789
  /**
26708
26790
  * @description Check if session should be started/stopped automatically
26709
26791
  * @param {ISession} [sessionPayload]
@@ -26951,6 +27033,28 @@ class SessionRecorder extends lib0_observable__WEBPACK_IMPORTED_MODULE_14__.Obse
26951
27033
  break;
26952
27034
  }
26953
27035
  }
27036
+ _normalizeError(error) {
27037
+ if (error instanceof Error)
27038
+ return error;
27039
+ if (typeof error === 'string')
27040
+ return new Error(error);
27041
+ try {
27042
+ return new Error(JSON.stringify(error));
27043
+ }
27044
+ catch (_e) {
27045
+ return new Error(String(error));
27046
+ }
27047
+ }
27048
+ _normalizeErrorInfo(errorInfo) {
27049
+ if (!errorInfo)
27050
+ return {};
27051
+ try {
27052
+ return JSON.parse(JSON.stringify(errorInfo));
27053
+ }
27054
+ catch (_e) {
27055
+ return { errorInfo: String(errorInfo) };
27056
+ }
27057
+ }
26954
27058
  }
26955
27059
 
26956
27060