@fluidframework/telemetry-utils 2.74.0 → 2.81.0

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.
Files changed (43) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/error.d.ts.map +1 -1
  3. package/dist/error.js +1 -1
  4. package/dist/error.js.map +1 -1
  5. package/dist/errorLogging.d.ts.map +1 -1
  6. package/dist/errorLogging.js +1 -0
  7. package/dist/errorLogging.js.map +1 -1
  8. package/dist/fluidErrorBase.d.ts.map +1 -1
  9. package/dist/fluidErrorBase.js +1 -1
  10. package/dist/fluidErrorBase.js.map +1 -1
  11. package/dist/index.d.ts +1 -1
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +2 -1
  14. package/dist/index.js.map +1 -1
  15. package/dist/layerCompatError.d.ts +21 -3
  16. package/dist/layerCompatError.d.ts.map +1 -1
  17. package/dist/layerCompatError.js +64 -4
  18. package/dist/layerCompatError.js.map +1 -1
  19. package/eslint.config.mts +4 -4
  20. package/lib/error.d.ts.map +1 -1
  21. package/lib/error.js +2 -2
  22. package/lib/error.js.map +1 -1
  23. package/lib/errorLogging.d.ts.map +1 -1
  24. package/lib/errorLogging.js +1 -0
  25. package/lib/errorLogging.js.map +1 -1
  26. package/lib/fluidErrorBase.d.ts.map +1 -1
  27. package/lib/fluidErrorBase.js +2 -2
  28. package/lib/fluidErrorBase.js.map +1 -1
  29. package/lib/index.d.ts +1 -1
  30. package/lib/index.d.ts.map +1 -1
  31. package/lib/index.js +1 -1
  32. package/lib/index.js.map +1 -1
  33. package/lib/layerCompatError.d.ts +21 -3
  34. package/lib/layerCompatError.d.ts.map +1 -1
  35. package/lib/layerCompatError.js +63 -3
  36. package/lib/layerCompatError.js.map +1 -1
  37. package/package.json +15 -15
  38. package/src/error.ts +1 -2
  39. package/src/errorLogging.ts +1 -0
  40. package/src/fluidErrorBase.ts +2 -4
  41. package/src/index.ts +1 -1
  42. package/src/layerCompatError.ts +77 -4
  43. package/.eslintrc.cjs +0 -11
@@ -11,13 +11,45 @@ import {
11
11
  } from "@fluid-internal/client-utils";
12
12
  import type { IErrorBase } from "@fluidframework/core-interfaces";
13
13
 
14
+ import type { MonitoringContext } from "./config.js";
14
15
  import { LayerIncompatibilityError } from "./error.js";
15
- import type { ITelemetryLoggerExt } from "./telemetryTypes.js";
16
+
17
+ /**
18
+ * The config key to disable layer compatibility validation.
19
+ * @internal
20
+ */
21
+ export const allowIncompatibleLayersKey = "Fluid.AllowIncompatibleLayers";
22
+
23
+ /**
24
+ * Tracks whether the event is logged when failing on layer incompatibility is bypassed via global config.
25
+ * This is used to ensure that the bypass event is only logged once per session so it does not flood telemetry.
26
+ */
27
+ let globalBypassLogged = false;
28
+
29
+ /**
30
+ * Tracks whether the event is logged when failing on layer incompatibility is bypassed due to missing
31
+ * compatibility details for each layer pair.
32
+ * This is used to ensure that the bypass event is only logged once per layer pair so it does not flood telemetry.
33
+ */
34
+ const strictCheckBypassLoggedForPair: Set<string> = new Set<string>();
16
35
 
17
36
  /**
18
37
  * Validates the compatibility between two layers using their compatibility details and support requirements.
19
- * If the layers are incompatible, it logs an "LayerIncompatibilityError" error event. It will also call the dispose
38
+ * If the layers are incompatible, it logs a "LayerIncompatibilityError" error event. It will also call the dispose
20
39
  * function with the error and throw the error.
40
+ * @param layer1 - The name of the first layer.
41
+ * @param layer2 - The name of the second layer.
42
+ * @param compatDetailsLayer1 - The compatibility details of the first layer.
43
+ * @param compatSupportRequirementsLayer1 - The support requirements that the second layer must meet to be compatible
44
+ * with the first layer.
45
+ * @param maybeCompatDetailsLayer2 - The compatibility details of the second layer. This can be undefined if the
46
+ * second layer does not provide compatibility details.
47
+ * @param disposeFn - A function that will be called with the error if the layers are incompatible.
48
+ * @param mc - The monitoring context for logging and reading configuration.
49
+ * @param strictCompatibilityCheck - If true, the function will use default compatibility details for the second layer if
50
+ * they are missing and use it for validation.
51
+ * If false, it will skip the compatibility check if the details are missing and just log an error.
52
+ * Defaults to false.
21
53
  *
22
54
  * @internal
23
55
  */
@@ -28,7 +60,8 @@ export function validateLayerCompatibility(
28
60
  compatSupportRequirementsLayer1: ILayerCompatSupportRequirements,
29
61
  maybeCompatDetailsLayer2: ILayerCompatDetails | undefined,
30
62
  disposeFn: (error?: IErrorBase) => void,
31
- logger: ITelemetryLoggerExt,
63
+ mc: MonitoringContext,
64
+ strictCompatibilityCheck: boolean = false,
32
65
  ): void {
33
66
  const layerCheckResult = checkLayerCompatibility(
34
67
  compatSupportRequirementsLayer1,
@@ -61,7 +94,47 @@ export function validateLayerCompatibility(
61
94
  details: JSON.stringify(detailedProperties),
62
95
  },
63
96
  );
64
- logger.sendErrorEvent(
97
+
98
+ if (mc.config.getBoolean(allowIncompatibleLayersKey) === true) {
99
+ // If the validation is explicitly disabled via config, do not fail. This config provides a way to bypass
100
+ // compatibility validation while this feature is being rolled out.
101
+ if (!globalBypassLogged) {
102
+ // This event is only logged once per session to avoid flooding telemetry.
103
+ globalBypassLogged = true;
104
+ mc.logger.sendTelemetryEvent(
105
+ {
106
+ eventName: "LayerIncompatibilityDetectedButBypassed",
107
+ reason: `${allowIncompatibleLayersKey} config is set to true`,
108
+ },
109
+ error,
110
+ );
111
+ }
112
+ return;
113
+ }
114
+
115
+ if (maybeCompatDetailsLayer2 === undefined && !strictCompatibilityCheck) {
116
+ // If there is no compatibility details for layer2 and strictCompatibilityCheck is false, do not fail.
117
+ // There can be a couple of scenarios where this can happen:
118
+ // 1. layer2's version is older than the version where compatibility enforcement was introduced. In this
119
+ // case, the behavior is the same as before compatibility enforcement was introduced.
120
+ // 2. layer2 has a custom implementation which doesn't provide compatibility details. In this case,
121
+ // we don't know for sure that it is incompatible. It may fail at a later point when it tries to use
122
+ // some feature that the Runtime doesn't support.
123
+ if (!strictCheckBypassLoggedForPair.has(`${layer1}-${layer2}`)) {
124
+ // This event is only logged once per session per layer combination to avoid flooding telemetry.
125
+ strictCheckBypassLoggedForPair.add(`${layer1}-${layer2}`);
126
+ mc.logger.sendTelemetryEvent(
127
+ {
128
+ eventName: "LayerIncompatibilityDetectedButBypassed",
129
+ reason: `No compatibility details provided for ${layer2} and strictCompatibilityCheck is false`,
130
+ },
131
+ error,
132
+ );
133
+ }
134
+ return;
135
+ }
136
+
137
+ mc.logger.sendErrorEvent(
65
138
  {
66
139
  eventName: "LayerIncompatibilityError",
67
140
  },
package/.eslintrc.cjs DELETED
@@ -1,11 +0,0 @@
1
- /*!
2
- * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
- * Licensed under the MIT License.
4
- */
5
-
6
- module.exports = {
7
- extends: [require.resolve("@fluidframework/eslint-config-fluid/strict"), "prettier"],
8
- parserOptions: {
9
- project: ["./tsconfig.json", "./src/test/tsconfig.json"],
10
- },
11
- };