@webex/internal-plugin-metrics 3.8.0-web-workers-keepalive.1 → 3.8.1-next.1

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.
@@ -3,7 +3,7 @@ import CallDiagnosticMetrics from './call-diagnostic/call-diagnostic-metrics';
3
3
  import BehavioralMetrics from './behavioral-metrics';
4
4
  import OperationalMetrics from './operational-metrics';
5
5
  import BusinessMetrics from './business-metrics';
6
- import { RecursivePartial, MetricEventProduct, MetricEventAgent, MetricEventVerb, ClientEvent, FeatureEvent, EventPayload, MediaQualityEvent, InternalEvent, SubmitClientEventOptions, Table } from './metrics.types';
6
+ import { RecursivePartial, MetricEventProduct, MetricEventAgent, MetricEventVerb, ClientEvent, FeatureEvent, EventPayload, MediaQualityEvent, InternalEvent, SubmitClientEventOptions, Table, DelayedClientEvent } from './metrics.types';
7
7
  import CallDiagnosticLatencies from './call-diagnostic/call-diagnostic-metrics-latencies';
8
8
  /**
9
9
  * Metrics plugin to centralize all types of metrics.
@@ -22,6 +22,10 @@ declare class Metrics extends WebexPlugin {
22
22
  * Whether or not to delay the submission of client events.
23
23
  */
24
24
  delaySubmitClientEvents: boolean;
25
+ /**
26
+ * Overrides for delayed client events. E.g. if you want to override the correlationId for all delayed client events, you can set this to { correlationId: 'newCorrelationId' }
27
+ */
28
+ delayedClientEventsOverrides: Partial<DelayedClientEvent['options']>;
25
29
  /**
26
30
  * Constructor
27
31
  * @param args
@@ -178,8 +182,11 @@ declare class Metrics extends WebexPlugin {
178
182
  * Sets the value of delaySubmitClientEvents. If set to true, client events will be delayed until submitDelayedClientEvents is called. If
179
183
  * set to false, delayed client events will be submitted.
180
184
  *
181
- * @param {boolean} shouldDelay - A boolean value indicating whether to delay the submission of client events.
185
+ * @param {object} options - {shouldDelay: A boolean value indicating whether to delay the submission of client events, overrides: An object containing overrides for the client events}
182
186
  */
183
- setDelaySubmitClientEvents(shouldDelay: boolean): Promise<any[]> | Promise<void>;
187
+ setDelaySubmitClientEvents({ shouldDelay, overrides, }: {
188
+ shouldDelay: boolean;
189
+ overrides?: Partial<DelayedClientEvent['options']>;
190
+ }): Promise<any[]> | Promise<void>;
184
191
  }
185
192
  export default Metrics;
package/package.json CHANGED
@@ -26,22 +26,22 @@
26
26
  "@webex/eslint-config-legacy": "0.0.0",
27
27
  "@webex/jest-config-legacy": "0.0.0",
28
28
  "@webex/legacy-tools": "0.0.0",
29
- "@webex/test-helper-chai": "3.8.0-web-workers-keepalive.1",
30
- "@webex/test-helper-mocha": "3.8.0-web-workers-keepalive.1",
31
- "@webex/test-helper-mock-webex": "3.8.0-web-workers-keepalive.1",
32
- "@webex/test-helper-test-users": "3.8.0-web-workers-keepalive.1",
29
+ "@webex/test-helper-chai": "3.8.1-next.1",
30
+ "@webex/test-helper-mocha": "3.8.1-next.1",
31
+ "@webex/test-helper-mock-webex": "3.8.1-next.1",
32
+ "@webex/test-helper-test-users": "3.8.1-next.1",
33
33
  "eslint": "^8.24.0",
34
34
  "prettier": "^2.7.1",
35
35
  "sinon": "^9.2.4"
36
36
  },
37
37
  "dependencies": {
38
- "@webex/common": "3.8.0-web-workers-keepalive.1",
39
- "@webex/common-timers": "3.8.0-web-workers-keepalive.1",
40
- "@webex/event-dictionary-ts": "^1.0.1688",
41
- "@webex/internal-plugin-metrics": "3.8.0-web-workers-keepalive.1",
42
- "@webex/test-helper-chai": "3.8.0-web-workers-keepalive.1",
43
- "@webex/test-helper-mock-webex": "3.8.0-web-workers-keepalive.1",
44
- "@webex/webex-core": "3.8.0-web-workers-keepalive.1",
38
+ "@webex/common": "3.8.1-next.1",
39
+ "@webex/common-timers": "3.8.1-next.1",
40
+ "@webex/event-dictionary-ts": "^1.0.1753",
41
+ "@webex/internal-plugin-metrics": "3.8.1-next.1",
42
+ "@webex/test-helper-chai": "3.8.1-next.1",
43
+ "@webex/test-helper-mock-webex": "3.8.1-next.1",
44
+ "@webex/webex-core": "3.8.1-next.1",
45
45
  "ip-anonymize": "^0.1.0",
46
46
  "lodash": "^4.17.21",
47
47
  "uuid": "^3.3.2"
@@ -54,5 +54,5 @@
54
54
  "test:style": "eslint ./src/**/*.*",
55
55
  "test:unit": "webex-legacy-tools test --unit --runner mocha"
56
56
  },
57
- "version": "3.8.0-web-workers-keepalive.1"
57
+ "version": "3.8.1-next.1"
58
58
  }
@@ -97,6 +97,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
97
97
  private hasLoggedBrowserSerial: boolean;
98
98
  private device: any;
99
99
  private delayedClientEvents: DelayedClientEvent[] = [];
100
+ private eventErrorCache: WeakMap<any, any> = new WeakMap();
101
+ private isMercuryConnected = false;
100
102
 
101
103
  // the default validator before piping an event to the batcher
102
104
  // this function can be overridden by the user
@@ -149,6 +151,16 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
149
151
  return undefined;
150
152
  }
151
153
 
154
+ /**
155
+ * Sets mercury connected status for event data object in CA events
156
+ * @public
157
+ * @param status - boolean value indicating mercury connection status
158
+ * @return {void}
159
+ */
160
+ public setMercuryConnectedStatus(status: boolean): void {
161
+ this.isMercuryConnected = status;
162
+ }
163
+
152
164
  /**
153
165
  * Returns meeting's subServiceType
154
166
  * @param meeting
@@ -555,16 +567,31 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
555
567
  return undefined;
556
568
  }
557
569
 
570
+ /**
571
+ * Clear the error cache
572
+ */
573
+ clearErrorCache() {
574
+ this.eventErrorCache = new WeakMap();
575
+ }
576
+
558
577
  /**
559
578
  * Generate error payload for Client Event
560
579
  * @param rawError
561
580
  */
562
581
  generateClientEventErrorPayload(rawError: any) {
582
+ const cachedError = this.eventErrorCache.get(rawError);
583
+
584
+ if (cachedError) {
585
+ return [cachedError, true];
586
+ }
587
+
563
588
  const rawErrorMessage = rawError.message;
564
589
  const httpStatusCode = rawError.statusCode;
590
+ let payload;
591
+
565
592
  if (rawError.name) {
566
593
  if (isBrowserMediaErrorName(rawError.name)) {
567
- return this.getErrorPayloadForClientErrorCode({
594
+ payload = this.getErrorPayloadForClientErrorCode({
568
595
  serviceErrorCode: undefined,
569
596
  clientErrorCode: BROWSER_MEDIA_ERROR_NAME_TO_CLIENT_ERROR_CODES_MAP[rawError.name],
570
597
  serviceErrorName: rawError.name,
@@ -574,11 +601,11 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
574
601
  }
575
602
  }
576
603
 
577
- if (isSdpOfferCreationError(rawError)) {
604
+ if (isSdpOfferCreationError(rawError) && !payload) {
578
605
  // error code is 30005, but that's not specific enough. we also need to check error.cause.type
579
606
  const causeType = rawError.cause?.type;
580
607
 
581
- return this.getErrorPayloadForClientErrorCode({
608
+ payload = this.getErrorPayloadForClientErrorCode({
582
609
  serviceErrorCode: undefined,
583
610
  clientErrorCode:
584
611
  SDP_OFFER_CREATION_ERROR_MAP[causeType] || SDP_OFFER_CREATION_ERROR_MAP.GENERAL,
@@ -596,8 +623,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
596
623
 
597
624
  if (serviceErrorCode) {
598
625
  const clientErrorCode = SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP[serviceErrorCode];
599
- if (clientErrorCode) {
600
- return this.getErrorPayloadForClientErrorCode({
626
+ if (clientErrorCode && !payload) {
627
+ payload = this.getErrorPayloadForClientErrorCode({
601
628
  clientErrorCode,
602
629
  serviceErrorCode,
603
630
  rawErrorMessage,
@@ -606,8 +633,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
606
633
  }
607
634
 
608
635
  // by default, if it is locus error, return new locus err
609
- if (isLocusServiceErrorCode(serviceErrorCode)) {
610
- return this.getErrorPayloadForClientErrorCode({
636
+ if (isLocusServiceErrorCode(serviceErrorCode) && !payload) {
637
+ payload = this.getErrorPayloadForClientErrorCode({
611
638
  clientErrorCode: NEW_LOCUS_ERROR_CLIENT_CODE,
612
639
  serviceErrorCode,
613
640
  rawErrorMessage,
@@ -616,8 +643,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
616
643
  }
617
644
  }
618
645
 
619
- if (isMeetingInfoServiceError(rawError)) {
620
- return this.getErrorPayloadForClientErrorCode({
646
+ if (isMeetingInfoServiceError(rawError) && !payload) {
647
+ payload = this.getErrorPayloadForClientErrorCode({
621
648
  clientErrorCode: MEETING_INFO_LOOKUP_ERROR_CLIENT_CODE,
622
649
  serviceErrorCode,
623
650
  rawErrorMessage,
@@ -625,8 +652,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
625
652
  });
626
653
  }
627
654
 
628
- if (isNetworkError(rawError)) {
629
- return this.getErrorPayloadForClientErrorCode({
655
+ if (isNetworkError(rawError) && !payload) {
656
+ payload = this.getErrorPayloadForClientErrorCode({
630
657
  clientErrorCode: NETWORK_ERROR,
631
658
  serviceErrorCode,
632
659
  payloadOverrides: rawError.payloadOverrides,
@@ -635,8 +662,8 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
635
662
  });
636
663
  }
637
664
 
638
- if (isUnauthorizedError(rawError)) {
639
- return this.getErrorPayloadForClientErrorCode({
665
+ if (isUnauthorizedError(rawError) && !payload) {
666
+ payload = this.getErrorPayloadForClientErrorCode({
640
667
  clientErrorCode: AUTHENTICATION_FAILED_CODE,
641
668
  serviceErrorCode,
642
669
  payloadOverrides: rawError.payloadOverrides,
@@ -645,15 +672,22 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
645
672
  });
646
673
  }
647
674
 
648
- // otherwise return unkown error but passing serviceErrorCode and serviceErrorName so that we know the issue
649
- return this.getErrorPayloadForClientErrorCode({
650
- clientErrorCode: UNKNOWN_ERROR,
651
- serviceErrorCode: serviceErrorCode || UNKNOWN_ERROR,
652
- serviceErrorName: rawError?.name,
653
- payloadOverrides: rawError.payloadOverrides,
654
- rawErrorMessage,
655
- httpStatusCode,
656
- });
675
+ if (!payload) {
676
+ // otherwise return unkown error but passing serviceErrorCode and serviceErrorName so that we know the issue
677
+ payload = this.getErrorPayloadForClientErrorCode({
678
+ clientErrorCode: UNKNOWN_ERROR,
679
+ serviceErrorCode: serviceErrorCode || UNKNOWN_ERROR,
680
+ serviceErrorName: rawError?.name,
681
+ payloadOverrides: rawError.payloadOverrides,
682
+ rawErrorMessage,
683
+ httpStatusCode,
684
+ });
685
+ }
686
+
687
+ // cache the payload for future use
688
+ this.eventErrorCache.set(rawError, payload);
689
+
690
+ return [payload, false];
657
691
  }
658
692
 
659
693
  /**
@@ -716,6 +750,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
716
750
  errors,
717
751
  eventData: {
718
752
  webClientDomain: window.location.hostname,
753
+ isMercuryConnected: this.isMercuryConnected,
719
754
  },
720
755
  userType: meeting.getCurUserType(),
721
756
  loginType:
@@ -784,6 +819,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
784
819
  identifiers,
785
820
  eventData: {
786
821
  webClientDomain: window.location.hostname,
822
+ isMercuryConnected: this.isMercuryConnected,
787
823
  },
788
824
  loginType: this.getCurLoginType(),
789
825
  // @ts-ignore
@@ -834,14 +870,14 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
834
870
  const errors: ClientEventPayloadError = [];
835
871
 
836
872
  if (rawError) {
837
- const generatedError = this.generateClientEventErrorPayload(rawError);
873
+ const [generatedError, cached] = this.generateClientEventErrorPayload(rawError);
838
874
  if (generatedError) {
839
875
  errors.push(generatedError);
840
876
  }
841
877
  this.logger.log(
842
878
  CALL_DIAGNOSTIC_LOG_IDENTIFIER,
843
879
  'CallDiagnosticMetrics: @prepareClientEvent. Generated errors:',
844
- `generatedError: ${JSON.stringify(generatedError)}`
880
+ `generatedError (cached: ${cached}): ${JSON.stringify(generatedError)}`
845
881
  );
846
882
  }
847
883
 
@@ -919,7 +955,7 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
919
955
  /**
920
956
  * Submit Delayed Client Event CA events. Clears delayedClientEvents array after submission.
921
957
  */
922
- public submitDelayedClientEvents() {
958
+ public submitDelayedClientEvents(overrides?: Partial<DelayedClientEvent['options']>) {
923
959
  this.logger.log(
924
960
  CALL_DIAGNOSTIC_LOG_IDENTIFIER,
925
961
  'CallDiagnosticMetrics: @submitDelayedClientEvents. Submitting delayed client events.'
@@ -930,7 +966,10 @@ export default class CallDiagnosticMetrics extends StatelessWebexPlugin {
930
966
  }
931
967
 
932
968
  const promises = this.delayedClientEvents.map((delayedSubmitClientEventParams) => {
933
- return this.submitClientEvent(delayedSubmitClientEventParams);
969
+ const {name, payload, options} = delayedSubmitClientEventParams;
970
+ const optionsWithOverrides: DelayedClientEvent['options'] = {...options, ...overrides};
971
+
972
+ return this.submitClientEvent({name, payload, options: optionsWithOverrides});
934
973
  });
935
974
 
936
975
  this.delayedClientEvents = [];
@@ -133,6 +133,7 @@ export const ERROR_DESCRIPTIONS = {
133
133
  SDP_OFFER_CREATION_ERROR: 'SdpOfferCreationError',
134
134
  SDP_OFFER_CREATION_ERROR_MISSING_CODEC: 'SdpOfferCreationErrorMissingCodec',
135
135
  WDM_RESTRICTED_REGION: 'WdmRestrictedRegion',
136
+ USER_NOT_ALLOWED_JOIN_WEBINAR: 'UserNotAllowedJoinWebinar',
136
137
  };
137
138
 
138
139
  export const SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP = {
@@ -151,6 +152,10 @@ export const SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP = {
151
152
  403004: 4005,
152
153
  // Wrong password. Meeting is not allow to access since password error
153
154
  403028: 4005,
155
+ // meeting is not allow to access since require panelist password
156
+ 403025: 4005,
157
+ // wrong password. Meeting is not allow to access since panelist password error
158
+ 403125: 4005,
154
159
  // Wrong or expired permission. Meeting is not allow to access since permissionToken error or expire
155
160
  403032: 4005,
156
161
  // Meeting is required login for current user
@@ -202,6 +207,24 @@ export const SERVICE_ERROR_CODES_TO_CLIENT_ERROR_CODES_MAP = {
202
207
  423013: 4005,
203
208
  // Too many requests access
204
209
  429005: 4100,
210
+ // Webinar: Meeting registration is required
211
+ 403021: 4104,
212
+ // Webinar: Meeting registration is still pending
213
+ 403022: 4104,
214
+ // Webinar: Meeting registration have been rejected
215
+ 403024: 4104,
216
+ // Webinar: Registration ID verified failure
217
+ 403137: 4104,
218
+ // Webinar: Registration ID input too many time,please input captcha code
219
+ 423007: 4104,
220
+ // Webinar: Need to join meeting via webcast
221
+ 403026: 4104,
222
+ // Webinar: Meeting join required registration ID
223
+ 403037: 4104,
224
+ // Not reach JBH, can't join meeting
225
+ 403003: 4101,
226
+ // Attendee email is required
227
+ 403030: 4101,
205
228
 
206
229
  // ---- Locus ------
207
230
  // FREE_USER_MAX_PARTICIPANTS_EXCEEDED
@@ -666,6 +689,11 @@ export const CLIENT_ERROR_CODE_TO_ERROR_PAYLOAD: Record<number, Partial<ClientEv
666
689
  category: 'expected',
667
690
  fatal: true,
668
691
  },
692
+ 4104: {
693
+ errorDescription: ERROR_DESCRIPTIONS.USER_NOT_ALLOWED_JOIN_WEBINAR,
694
+ category: 'expected',
695
+ fatal: true,
696
+ },
669
697
  2729: {
670
698
  errorDescription: ERROR_DESCRIPTIONS.NO_MEDIA_FOUND,
671
699
  category: 'expected',
@@ -22,6 +22,7 @@ import {
22
22
  InternalEvent,
23
23
  SubmitClientEventOptions,
24
24
  Table,
25
+ DelayedClientEvent,
25
26
  } from './metrics.types';
26
27
  import CallDiagnosticLatencies from './call-diagnostic/call-diagnostic-metrics-latencies';
27
28
  import {setMetricTimings} from './call-diagnostic/call-diagnostic-metrics.util';
@@ -50,6 +51,11 @@ class Metrics extends WebexPlugin {
50
51
  */
51
52
  delaySubmitClientEvents = false;
52
53
 
54
+ /**
55
+ * Overrides for delayed client events. E.g. if you want to override the correlationId for all delayed client events, you can set this to { correlationId: 'newCorrelationId' }
56
+ */
57
+ delayedClientEventsOverrides: Partial<DelayedClientEvent['options']> = {};
58
+
53
59
  /**
54
60
  * Constructor
55
61
  * @param args
@@ -74,6 +80,10 @@ class Metrics extends WebexPlugin {
74
80
  // @ts-ignore
75
81
  this.callDiagnosticMetrics = new CallDiagnosticMetrics({}, {parent: this.webex});
76
82
  this.isReady = true;
83
+ this.setDelaySubmitClientEvents({
84
+ shouldDelay: this.delaySubmitClientEvents,
85
+ overrides: this.delayedClientEventsOverrides,
86
+ });
77
87
  });
78
88
  }
79
89
 
@@ -404,13 +414,20 @@ class Metrics extends WebexPlugin {
404
414
  * Sets the value of delaySubmitClientEvents. If set to true, client events will be delayed until submitDelayedClientEvents is called. If
405
415
  * set to false, delayed client events will be submitted.
406
416
  *
407
- * @param {boolean} shouldDelay - A boolean value indicating whether to delay the submission of client events.
417
+ * @param {object} options - {shouldDelay: A boolean value indicating whether to delay the submission of client events, overrides: An object containing overrides for the client events}
408
418
  */
409
- public setDelaySubmitClientEvents(shouldDelay: boolean) {
419
+ public setDelaySubmitClientEvents({
420
+ shouldDelay,
421
+ overrides,
422
+ }: {
423
+ shouldDelay: boolean;
424
+ overrides?: Partial<DelayedClientEvent['options']>;
425
+ }) {
410
426
  this.delaySubmitClientEvents = shouldDelay;
427
+ this.delayedClientEventsOverrides = overrides || {};
411
428
 
412
- if (!shouldDelay) {
413
- return this.callDiagnosticMetrics.submitDelayedClientEvents();
429
+ if (this.isReady && !shouldDelay) {
430
+ return this.callDiagnosticMetrics.submitDelayedClientEvents(overrides);
414
431
  }
415
432
 
416
433
  return Promise.resolve();