@fluidframework/telemetry-utils 2.74.0 → 2.80.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.
- package/CHANGELOG.md +4 -0
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js +1 -1
- package/dist/error.js.map +1 -1
- package/dist/fluidErrorBase.d.ts.map +1 -1
- package/dist/fluidErrorBase.js +1 -1
- package/dist/fluidErrorBase.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/layerCompatError.d.ts +21 -3
- package/dist/layerCompatError.d.ts.map +1 -1
- package/dist/layerCompatError.js +64 -4
- package/dist/layerCompatError.js.map +1 -1
- package/lib/error.d.ts.map +1 -1
- package/lib/error.js +2 -2
- package/lib/error.js.map +1 -1
- package/lib/fluidErrorBase.d.ts.map +1 -1
- package/lib/fluidErrorBase.js +2 -2
- package/lib/fluidErrorBase.js.map +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +1 -1
- package/lib/index.js.map +1 -1
- package/lib/layerCompatError.d.ts +21 -3
- package/lib/layerCompatError.d.ts.map +1 -1
- package/lib/layerCompatError.js +63 -3
- package/lib/layerCompatError.js.map +1 -1
- package/package.json +15 -15
- package/src/error.ts +1 -2
- package/src/fluidErrorBase.ts +2 -4
- package/src/index.ts +1 -1
- package/src/layerCompatError.ts +77 -4
package/CHANGELOG.md
CHANGED
package/dist/error.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAC5F,OAAO,
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"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"}
|
package/dist/error.js
CHANGED
|
@@ -166,7 +166,7 @@ class LayerIncompatibilityError extends errorLogging_js_1.LoggingError {
|
|
|
166
166
|
...telemetryProps,
|
|
167
167
|
layerIncompatibilityError: true,
|
|
168
168
|
});
|
|
169
|
-
this.errorType = internal_1.
|
|
169
|
+
this.errorType = internal_1.FluidErrorTypes.layerIncompatibilityError;
|
|
170
170
|
this.layer = incompatibilityProps.layer;
|
|
171
171
|
this.layerVersion = incompatibilityProps.layerVersion;
|
|
172
172
|
this.incompatibleLayer = incompatibilityProps.incompatibleLayer;
|
package/dist/error.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { IErrorBase, ITelemetryBaseProperties } from \"@fluidframework/core-interfaces\";\nimport {\n\tFluidErrorTypes,\n\tFluidErrorTypesAlpha,\n\ttype IGenericError,\n\ttype ILayerIncompatibilityError,\n\ttype IUsageError,\n} from \"@fluidframework/core-interfaces/internal\";\nimport type { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\n\nimport {\n\tLoggingError,\n\tNORMALIZED_ERROR_TYPE,\n\tisExternalError,\n\tnormalizeError,\n\twrapError,\n} from \"./errorLogging.js\";\nimport type { IFluidErrorBase } from \"./fluidErrorBase.js\";\nimport type { ITelemetryPropertiesExt } from \"./telemetryTypes.js\";\n\n/**\n * Throws a UsageError with the given message if the condition is not met.\n * Use this API when `false` indicates a precondition is not met on a public API (for any FF layer).\n *\n * @param condition - The condition that should be true, if the condition is false a UsageError will be thrown.\n * @param message - The message to include in the error when the condition does not hold.\n * @param props - Telemetry props to include on the error when the condition does not hold.\n * @internal\n */\nexport function validatePrecondition(\n\tcondition: boolean,\n\tmessage: string,\n\tprops?: ITelemetryBaseProperties,\n): asserts condition {\n\tif (!condition) {\n\t\tthrow new UsageError(message, props);\n\t}\n}\n\n/**\n * Generic wrapper for an unrecognized/uncategorized error object\n *\n * @internal\n */\nexport class GenericError extends LoggingError implements IGenericError, IFluidErrorBase {\n\tpublic readonly errorType = FluidErrorTypes.genericError;\n\n\t/**\n\t * Create a new GenericError\n\t * @param message - Error message\n\t * @param error - inner error object\n\t * @param props - Telemetry props to include when the error is logged\n\t */\n\tpublic constructor(\n\t\tmessage: string,\n\t\t// TODO: Use `unknown` instead (API breaking change because error is not just an input parameter, but a public member of the class)\n\t\t// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any\n\t\tpublic readonly error?: any,\n\t\tprops?: ITelemetryBaseProperties,\n\t) {\n\t\t// Don't try to log the inner error\n\t\tsuper(message, props, new Set([\"error\"]));\n\t}\n}\n\n/**\n * Error indicating an API is being used improperly resulting in an invalid operation.\n *\n * @internal\n */\nexport class UsageError extends LoggingError implements IUsageError, IFluidErrorBase {\n\tpublic readonly errorType = FluidErrorTypes.usageError;\n\n\tpublic constructor(message: string, props?: ITelemetryBaseProperties) {\n\t\tsuper(message, { ...props, usageError: true });\n\t}\n}\n\n/**\n * DataCorruptionError indicates that we encountered definitive evidence that the data at rest\n * backing this container is corrupted, and this container would never be expected to load properly again\n *\n * @internal\n */\nexport class DataCorruptionError extends LoggingError implements IErrorBase, IFluidErrorBase {\n\tpublic readonly errorType = FluidErrorTypes.dataCorruptionError;\n\tpublic readonly canRetry = false;\n\n\tpublic constructor(message: string, props: ITelemetryBaseProperties) {\n\t\tsuper(message, { ...props, dataProcessingError: 1 });\n\t}\n}\n\n/**\n * Indicates we hit a fatal error while processing incoming data from the Fluid Service.\n *\n * @remarks\n *\n * The error will often originate in the dataStore or DDS implementation that is responding to incoming changes.\n * This differs from {@link DataCorruptionError} in that this may be a transient error that will not repro in another\n * client or session.\n *\n * @internal\n */\nexport class DataProcessingError extends LoggingError implements IErrorBase, IFluidErrorBase {\n\t/**\n\t * {@inheritDoc IFluidErrorBase.errorType}\n\t */\n\tpublic readonly errorType = FluidErrorTypes.dataProcessingError;\n\n\tpublic readonly canRetry = false;\n\n\tprivate constructor(errorMessage: string, props?: ITelemetryBaseProperties) {\n\t\tsuper(errorMessage, props);\n\t}\n\n\t/**\n\t * Create a new `DataProcessingError` detected and raised within the Fluid Framework.\n\t */\n\tpublic static create(\n\t\terrorMessage: string,\n\t\tdataProcessingCodepath: string,\n\t\tmessageLike?: Partial<\n\t\t\tPick<\n\t\t\t\tISequencedDocumentMessage,\n\t\t\t\t| \"clientId\"\n\t\t\t\t| \"sequenceNumber\"\n\t\t\t\t| \"clientSequenceNumber\"\n\t\t\t\t| \"referenceSequenceNumber\"\n\t\t\t\t| \"minimumSequenceNumber\"\n\t\t\t\t| \"timestamp\"\n\t\t\t>\n\t\t>,\n\t\tprops: ITelemetryPropertiesExt = {},\n\t\tstackTraceLimit?: number,\n\t): IFluidErrorBase {\n\t\tconst ErrorConfig = Error as unknown as { stackTraceLimit: number };\n\t\tconst originalStackTraceLimit = ErrorConfig.stackTraceLimit;\n\t\ttry {\n\t\t\tif (stackTraceLimit !== undefined) {\n\t\t\t\tErrorConfig.stackTraceLimit = stackTraceLimit;\n\t\t\t}\n\n\t\t\tconst dataProcessingError = DataProcessingError.wrapIfUnrecognized(\n\t\t\t\terrorMessage,\n\t\t\t\tdataProcessingCodepath,\n\t\t\t\tmessageLike,\n\t\t\t);\n\t\t\tdataProcessingError.addTelemetryProperties(props);\n\n\t\t\treturn dataProcessingError;\n\t\t} finally {\n\t\t\t// Reset the stack trace limit to the original value\n\t\t\tif (stackTraceLimit !== undefined) {\n\t\t\t\tErrorConfig.stackTraceLimit = originalStackTraceLimit;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Wrap the given error in a `DataProcessingError`, unless the error is already of a known type\n\t * with the exception of a normalized {@link LoggingError}, which will still be wrapped.\n\t *\n\t * In either case, the error will have some relevant properties added for telemetry.\n\t *\n\t * @remarks\n\t *\n\t * We wrap conditionally since known error types represent well-understood failure modes, and ideally\n\t * one day we will move away from throwing these errors but rather we'll return them.\n\t * But an unrecognized error needs to be classified as `DataProcessingError`.\n\t *\n\t * @param originalError - The error to be converted.\n\t * @param dataProcessingCodepath - Which code-path failed while processing data.\n\t * @param messageLike - Message to include info about via telemetry props.\n\t *\n\t * @returns Either a new `DataProcessingError`, or (if wrapping is deemed unnecessary) the given error.\n\t */\n\tpublic static wrapIfUnrecognized(\n\t\toriginalError: unknown,\n\t\tdataProcessingCodepath: string,\n\t\tmessageLike?: Partial<\n\t\t\tPick<\n\t\t\t\tISequencedDocumentMessage,\n\t\t\t\t| \"clientId\"\n\t\t\t\t| \"sequenceNumber\"\n\t\t\t\t| \"clientSequenceNumber\"\n\t\t\t\t| \"referenceSequenceNumber\"\n\t\t\t\t| \"minimumSequenceNumber\"\n\t\t\t\t| \"timestamp\"\n\t\t\t>\n\t\t>,\n\t): IFluidErrorBase {\n\t\tconst props = {\n\t\t\tdataProcessingError: 1,\n\t\t\tdataProcessingCodepath,\n\t\t\t...(messageLike === undefined\n\t\t\t\t? undefined\n\t\t\t\t: extractSafePropertiesFromMessage(messageLike)),\n\t\t};\n\n\t\tconst normalizedError = normalizeError(originalError, { props });\n\t\t// Note that other errors may have the NORMALIZED_ERROR_TYPE errorType,\n\t\t// but if so they are still suitable to be wrapped as DataProcessingError.\n\t\tif (\n\t\t\tisExternalError(normalizedError) ||\n\t\t\tnormalizedError.errorType === NORMALIZED_ERROR_TYPE\n\t\t) {\n\t\t\t// Create a new DataProcessingError to wrap this external error\n\t\t\tconst dataProcessingError = wrapError(\n\t\t\t\tnormalizedError,\n\t\t\t\t(message: string) => new DataProcessingError(message),\n\t\t\t);\n\n\t\t\t// Copy over the props above and any others added to this error since first being normalized\n\t\t\tdataProcessingError.addTelemetryProperties(normalizedError.getTelemetryProperties());\n\n\t\t\treturn dataProcessingError;\n\t\t}\n\t\treturn normalizedError;\n\t}\n}\n\n/**\n * Error indicating that two Fluid layers are incompatible.\n * See {@link @fluidframework/core-interfaces#ILayerIncompatibilityError} for more details.\n *\n * @internal\n */\nexport class LayerIncompatibilityError\n\textends LoggingError\n\timplements ILayerIncompatibilityError\n{\n\tpublic readonly errorType = FluidErrorTypesAlpha.layerIncompatibilityError;\n\tpublic readonly layer: string;\n\tpublic readonly layerVersion: string;\n\tpublic readonly incompatibleLayer: string;\n\tpublic readonly incompatibleLayerVersion: string;\n\tpublic readonly compatibilityRequirementsInMonths: number;\n\tpublic readonly actualDifferenceInMonths: number;\n\tpublic readonly details: string;\n\n\tpublic constructor(\n\t\tmessage: string,\n\t\tincompatibilityProps: {\n\t\t\tlayer: string;\n\t\t\tlayerVersion: string;\n\t\t\tincompatibleLayer: string;\n\t\t\tincompatibleLayerVersion: string;\n\t\t\tcompatibilityRequirementsInMonths: number;\n\t\t\tactualDifferenceInMonths: number;\n\t\t\tdetails: string;\n\t\t},\n\t\ttelemetryProps?: ITelemetryBaseProperties,\n\t) {\n\t\tsuper(message, {\n\t\t\t...incompatibilityProps,\n\t\t\t...telemetryProps,\n\t\t\tlayerIncompatibilityError: true,\n\t\t});\n\t\tthis.layer = incompatibilityProps.layer;\n\t\tthis.layerVersion = incompatibilityProps.layerVersion;\n\t\tthis.incompatibleLayer = incompatibilityProps.incompatibleLayer;\n\t\tthis.incompatibleLayerVersion = incompatibilityProps.incompatibleLayerVersion;\n\t\tthis.compatibilityRequirementsInMonths =\n\t\t\tincompatibilityProps.compatibilityRequirementsInMonths;\n\t\tthis.actualDifferenceInMonths = incompatibilityProps.actualDifferenceInMonths;\n\t\tthis.details = incompatibilityProps.details;\n\t}\n}\n\n/**\n * Extracts specific properties from the provided message that we know are safe to log.\n *\n * @param messageLike - Message to include info about via telemetry props.\n *\n * @internal\n */\nexport const extractSafePropertiesFromMessage = (\n\tmessageLike: Partial<\n\t\tPick<\n\t\t\tISequencedDocumentMessage,\n\t\t\t| \"clientId\"\n\t\t\t| \"sequenceNumber\"\n\t\t\t| \"clientSequenceNumber\"\n\t\t\t| \"referenceSequenceNumber\"\n\t\t\t| \"minimumSequenceNumber\"\n\t\t\t| \"timestamp\"\n\t\t>\n\t>,\n): {\n\tmessageClientId: string | undefined;\n\tmessageSequenceNumber: number | undefined;\n\tmessageClientSequenceNumber: number | undefined;\n\tmessageReferenceSequenceNumber: number | undefined;\n\tmessageMinimumSequenceNumber: number | undefined;\n\tmessageTimestamp: number | undefined;\n} => ({\n\tmessageClientId: messageLike.clientId === null ? \"null\" : messageLike.clientId,\n\tmessageSequenceNumber: messageLike.sequenceNumber,\n\tmessageClientSequenceNumber: messageLike.clientSequenceNumber,\n\tmessageReferenceSequenceNumber: messageLike.referenceSequenceNumber,\n\tmessageMinimumSequenceNumber: messageLike.minimumSequenceNumber,\n\tmessageTimestamp: messageLike.timestamp,\n});\n"]}
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { IErrorBase, ITelemetryBaseProperties } from \"@fluidframework/core-interfaces\";\nimport {\n\tFluidErrorTypes,\n\ttype IGenericError,\n\ttype ILayerIncompatibilityError,\n\ttype IUsageError,\n} from \"@fluidframework/core-interfaces/internal\";\nimport type { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\n\nimport {\n\tLoggingError,\n\tNORMALIZED_ERROR_TYPE,\n\tisExternalError,\n\tnormalizeError,\n\twrapError,\n} from \"./errorLogging.js\";\nimport type { IFluidErrorBase } from \"./fluidErrorBase.js\";\nimport type { ITelemetryPropertiesExt } from \"./telemetryTypes.js\";\n\n/**\n * Throws a UsageError with the given message if the condition is not met.\n * Use this API when `false` indicates a precondition is not met on a public API (for any FF layer).\n *\n * @param condition - The condition that should be true, if the condition is false a UsageError will be thrown.\n * @param message - The message to include in the error when the condition does not hold.\n * @param props - Telemetry props to include on the error when the condition does not hold.\n * @internal\n */\nexport function validatePrecondition(\n\tcondition: boolean,\n\tmessage: string,\n\tprops?: ITelemetryBaseProperties,\n): asserts condition {\n\tif (!condition) {\n\t\tthrow new UsageError(message, props);\n\t}\n}\n\n/**\n * Generic wrapper for an unrecognized/uncategorized error object\n *\n * @internal\n */\nexport class GenericError extends LoggingError implements IGenericError, IFluidErrorBase {\n\tpublic readonly errorType = FluidErrorTypes.genericError;\n\n\t/**\n\t * Create a new GenericError\n\t * @param message - Error message\n\t * @param error - inner error object\n\t * @param props - Telemetry props to include when the error is logged\n\t */\n\tpublic constructor(\n\t\tmessage: string,\n\t\t// TODO: Use `unknown` instead (API breaking change because error is not just an input parameter, but a public member of the class)\n\t\t// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any\n\t\tpublic readonly error?: any,\n\t\tprops?: ITelemetryBaseProperties,\n\t) {\n\t\t// Don't try to log the inner error\n\t\tsuper(message, props, new Set([\"error\"]));\n\t}\n}\n\n/**\n * Error indicating an API is being used improperly resulting in an invalid operation.\n *\n * @internal\n */\nexport class UsageError extends LoggingError implements IUsageError, IFluidErrorBase {\n\tpublic readonly errorType = FluidErrorTypes.usageError;\n\n\tpublic constructor(message: string, props?: ITelemetryBaseProperties) {\n\t\tsuper(message, { ...props, usageError: true });\n\t}\n}\n\n/**\n * DataCorruptionError indicates that we encountered definitive evidence that the data at rest\n * backing this container is corrupted, and this container would never be expected to load properly again\n *\n * @internal\n */\nexport class DataCorruptionError extends LoggingError implements IErrorBase, IFluidErrorBase {\n\tpublic readonly errorType = FluidErrorTypes.dataCorruptionError;\n\tpublic readonly canRetry = false;\n\n\tpublic constructor(message: string, props: ITelemetryBaseProperties) {\n\t\tsuper(message, { ...props, dataProcessingError: 1 });\n\t}\n}\n\n/**\n * Indicates we hit a fatal error while processing incoming data from the Fluid Service.\n *\n * @remarks\n *\n * The error will often originate in the dataStore or DDS implementation that is responding to incoming changes.\n * This differs from {@link DataCorruptionError} in that this may be a transient error that will not repro in another\n * client or session.\n *\n * @internal\n */\nexport class DataProcessingError extends LoggingError implements IErrorBase, IFluidErrorBase {\n\t/**\n\t * {@inheritDoc IFluidErrorBase.errorType}\n\t */\n\tpublic readonly errorType = FluidErrorTypes.dataProcessingError;\n\n\tpublic readonly canRetry = false;\n\n\tprivate constructor(errorMessage: string, props?: ITelemetryBaseProperties) {\n\t\tsuper(errorMessage, props);\n\t}\n\n\t/**\n\t * Create a new `DataProcessingError` detected and raised within the Fluid Framework.\n\t */\n\tpublic static create(\n\t\terrorMessage: string,\n\t\tdataProcessingCodepath: string,\n\t\tmessageLike?: Partial<\n\t\t\tPick<\n\t\t\t\tISequencedDocumentMessage,\n\t\t\t\t| \"clientId\"\n\t\t\t\t| \"sequenceNumber\"\n\t\t\t\t| \"clientSequenceNumber\"\n\t\t\t\t| \"referenceSequenceNumber\"\n\t\t\t\t| \"minimumSequenceNumber\"\n\t\t\t\t| \"timestamp\"\n\t\t\t>\n\t\t>,\n\t\tprops: ITelemetryPropertiesExt = {},\n\t\tstackTraceLimit?: number,\n\t): IFluidErrorBase {\n\t\tconst ErrorConfig = Error as unknown as { stackTraceLimit: number };\n\t\tconst originalStackTraceLimit = ErrorConfig.stackTraceLimit;\n\t\ttry {\n\t\t\tif (stackTraceLimit !== undefined) {\n\t\t\t\tErrorConfig.stackTraceLimit = stackTraceLimit;\n\t\t\t}\n\n\t\t\tconst dataProcessingError = DataProcessingError.wrapIfUnrecognized(\n\t\t\t\terrorMessage,\n\t\t\t\tdataProcessingCodepath,\n\t\t\t\tmessageLike,\n\t\t\t);\n\t\t\tdataProcessingError.addTelemetryProperties(props);\n\n\t\t\treturn dataProcessingError;\n\t\t} finally {\n\t\t\t// Reset the stack trace limit to the original value\n\t\t\tif (stackTraceLimit !== undefined) {\n\t\t\t\tErrorConfig.stackTraceLimit = originalStackTraceLimit;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Wrap the given error in a `DataProcessingError`, unless the error is already of a known type\n\t * with the exception of a normalized {@link LoggingError}, which will still be wrapped.\n\t *\n\t * In either case, the error will have some relevant properties added for telemetry.\n\t *\n\t * @remarks\n\t *\n\t * We wrap conditionally since known error types represent well-understood failure modes, and ideally\n\t * one day we will move away from throwing these errors but rather we'll return them.\n\t * But an unrecognized error needs to be classified as `DataProcessingError`.\n\t *\n\t * @param originalError - The error to be converted.\n\t * @param dataProcessingCodepath - Which code-path failed while processing data.\n\t * @param messageLike - Message to include info about via telemetry props.\n\t *\n\t * @returns Either a new `DataProcessingError`, or (if wrapping is deemed unnecessary) the given error.\n\t */\n\tpublic static wrapIfUnrecognized(\n\t\toriginalError: unknown,\n\t\tdataProcessingCodepath: string,\n\t\tmessageLike?: Partial<\n\t\t\tPick<\n\t\t\t\tISequencedDocumentMessage,\n\t\t\t\t| \"clientId\"\n\t\t\t\t| \"sequenceNumber\"\n\t\t\t\t| \"clientSequenceNumber\"\n\t\t\t\t| \"referenceSequenceNumber\"\n\t\t\t\t| \"minimumSequenceNumber\"\n\t\t\t\t| \"timestamp\"\n\t\t\t>\n\t\t>,\n\t): IFluidErrorBase {\n\t\tconst props = {\n\t\t\tdataProcessingError: 1,\n\t\t\tdataProcessingCodepath,\n\t\t\t...(messageLike === undefined\n\t\t\t\t? undefined\n\t\t\t\t: extractSafePropertiesFromMessage(messageLike)),\n\t\t};\n\n\t\tconst normalizedError = normalizeError(originalError, { props });\n\t\t// Note that other errors may have the NORMALIZED_ERROR_TYPE errorType,\n\t\t// but if so they are still suitable to be wrapped as DataProcessingError.\n\t\tif (\n\t\t\tisExternalError(normalizedError) ||\n\t\t\tnormalizedError.errorType === NORMALIZED_ERROR_TYPE\n\t\t) {\n\t\t\t// Create a new DataProcessingError to wrap this external error\n\t\t\tconst dataProcessingError = wrapError(\n\t\t\t\tnormalizedError,\n\t\t\t\t(message: string) => new DataProcessingError(message),\n\t\t\t);\n\n\t\t\t// Copy over the props above and any others added to this error since first being normalized\n\t\t\tdataProcessingError.addTelemetryProperties(normalizedError.getTelemetryProperties());\n\n\t\t\treturn dataProcessingError;\n\t\t}\n\t\treturn normalizedError;\n\t}\n}\n\n/**\n * Error indicating that two Fluid layers are incompatible.\n * See {@link @fluidframework/core-interfaces#ILayerIncompatibilityError} for more details.\n *\n * @internal\n */\nexport class LayerIncompatibilityError\n\textends LoggingError\n\timplements ILayerIncompatibilityError\n{\n\tpublic readonly errorType = FluidErrorTypes.layerIncompatibilityError;\n\tpublic readonly layer: string;\n\tpublic readonly layerVersion: string;\n\tpublic readonly incompatibleLayer: string;\n\tpublic readonly incompatibleLayerVersion: string;\n\tpublic readonly compatibilityRequirementsInMonths: number;\n\tpublic readonly actualDifferenceInMonths: number;\n\tpublic readonly details: string;\n\n\tpublic constructor(\n\t\tmessage: string,\n\t\tincompatibilityProps: {\n\t\t\tlayer: string;\n\t\t\tlayerVersion: string;\n\t\t\tincompatibleLayer: string;\n\t\t\tincompatibleLayerVersion: string;\n\t\t\tcompatibilityRequirementsInMonths: number;\n\t\t\tactualDifferenceInMonths: number;\n\t\t\tdetails: string;\n\t\t},\n\t\ttelemetryProps?: ITelemetryBaseProperties,\n\t) {\n\t\tsuper(message, {\n\t\t\t...incompatibilityProps,\n\t\t\t...telemetryProps,\n\t\t\tlayerIncompatibilityError: true,\n\t\t});\n\t\tthis.layer = incompatibilityProps.layer;\n\t\tthis.layerVersion = incompatibilityProps.layerVersion;\n\t\tthis.incompatibleLayer = incompatibilityProps.incompatibleLayer;\n\t\tthis.incompatibleLayerVersion = incompatibilityProps.incompatibleLayerVersion;\n\t\tthis.compatibilityRequirementsInMonths =\n\t\t\tincompatibilityProps.compatibilityRequirementsInMonths;\n\t\tthis.actualDifferenceInMonths = incompatibilityProps.actualDifferenceInMonths;\n\t\tthis.details = incompatibilityProps.details;\n\t}\n}\n\n/**\n * Extracts specific properties from the provided message that we know are safe to log.\n *\n * @param messageLike - Message to include info about via telemetry props.\n *\n * @internal\n */\nexport const extractSafePropertiesFromMessage = (\n\tmessageLike: Partial<\n\t\tPick<\n\t\t\tISequencedDocumentMessage,\n\t\t\t| \"clientId\"\n\t\t\t| \"sequenceNumber\"\n\t\t\t| \"clientSequenceNumber\"\n\t\t\t| \"referenceSequenceNumber\"\n\t\t\t| \"minimumSequenceNumber\"\n\t\t\t| \"timestamp\"\n\t\t>\n\t>,\n): {\n\tmessageClientId: string | undefined;\n\tmessageSequenceNumber: number | undefined;\n\tmessageClientSequenceNumber: number | undefined;\n\tmessageReferenceSequenceNumber: number | undefined;\n\tmessageMinimumSequenceNumber: number | undefined;\n\tmessageTimestamp: number | undefined;\n} => ({\n\tmessageClientId: messageLike.clientId === null ? \"null\" : messageLike.clientId,\n\tmessageSequenceNumber: messageLike.sequenceNumber,\n\tmessageClientSequenceNumber: messageLike.clientSequenceNumber,\n\tmessageReferenceSequenceNumber: messageLike.referenceSequenceNumber,\n\tmessageMinimumSequenceNumber: messageLike.minimumSequenceNumber,\n\tmessageTimestamp: messageLike.timestamp,\n});\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fluidErrorBase.d.ts","sourceRoot":"","sources":["../src/fluidErrorBase.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAChF,OAAO,EAEN,KAAK,0BAA0B,EAC/B,MAAM,0CAA0C,CAAC;AAElD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAEnE;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,eAAgB,SAAQ,KAAK;IAC7C;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B;;;;;;;;;OASG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;;;;;;OAOG;IACH,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IAEjC;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;OAEG;IACH,sBAAsB,IAAI,wBAAwB,CAAC;IAEnD;;OAEG;IACH,sBAAsB,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,IAAI,CAAC;CACjE;AAMD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,MAAO,OAAO;qBAA2B,MAAM;CACG,CAAC;AAElF;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,eAAe,CAOrE;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAC1C,KAAK,EAAE,OAAO,GACZ,KAAK,IAAI,0BAA0B,
|
|
1
|
+
{"version":3,"file":"fluidErrorBase.d.ts","sourceRoot":"","sources":["../src/fluidErrorBase.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAChF,OAAO,EAEN,KAAK,0BAA0B,EAC/B,MAAM,0CAA0C,CAAC;AAElD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAEnE;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,eAAgB,SAAQ,KAAK;IAC7C;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B;;;;;;;;;OASG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;;;;;;OAOG;IACH,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IAEjC;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;OAEG;IACH,sBAAsB,IAAI,wBAAwB,CAAC;IAEnD;;OAEG;IACH,sBAAsB,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,IAAI,CAAC;CACjE;AAMD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,MAAO,OAAO;qBAA2B,MAAM;CACG,CAAC;AAElF;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,eAAe,CAOrE;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAC1C,KAAK,EAAE,OAAO,GACZ,KAAK,IAAI,0BAA0B,CAErC"}
|
package/dist/fluidErrorBase.js
CHANGED
|
@@ -33,7 +33,7 @@ exports.isFluidError = isFluidError;
|
|
|
33
33
|
* @internal
|
|
34
34
|
*/
|
|
35
35
|
function isLayerIncompatibilityError(error) {
|
|
36
|
-
return
|
|
36
|
+
return isFluidError(error) && error.errorType === internal_1.FluidErrorTypes.layerIncompatibilityError;
|
|
37
37
|
}
|
|
38
38
|
exports.isLayerIncompatibilityError = isLayerIncompatibilityError;
|
|
39
39
|
//# sourceMappingURL=fluidErrorBase.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fluidErrorBase.js","sourceRoot":"","sources":["../src/fluidErrorBase.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,uEAGkD;AAkFlD,MAAM,yBAAyB,GAAG,CAAC,CAAU,EAAW,EAAE,CACzD,OAAQ,CAA8B,EAAE,sBAAsB,KAAK,UAAU;IAC7E,OAAQ,CAA8B,EAAE,sBAAsB,KAAK,UAAU,CAAC;AAE/E;;;;GAIG;AACI,MAAM,kBAAkB,GAAG,CAAC,CAAU,EAAoC,EAAE,CAClF,OAAQ,CAA0C,EAAE,eAAe,KAAK,QAAQ,CAAC;AADrE,QAAA,kBAAkB,sBACmD;AAElF;;;;GAIG;AACH,SAAgB,YAAY,CAAC,KAAc;IAC1C,OAAO,CACN,OAAQ,KAAkC,EAAE,SAAS,KAAK,QAAQ;QAClE,OAAQ,KAAkC,EAAE,OAAO,KAAK,QAAQ;QAChE,IAAA,0BAAkB,EAAC,KAAK,CAAC;QACzB,yBAAyB,CAAC,KAAK,CAAC,CAChC,CAAC;AACH,CAAC;AAPD,oCAOC;AAED;;;;GAIG;AACH,SAAgB,2BAA2B,CAC1C,KAAc;IAEd,OAAO,
|
|
1
|
+
{"version":3,"file":"fluidErrorBase.js","sourceRoot":"","sources":["../src/fluidErrorBase.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAGH,uEAGkD;AAkFlD,MAAM,yBAAyB,GAAG,CAAC,CAAU,EAAW,EAAE,CACzD,OAAQ,CAA8B,EAAE,sBAAsB,KAAK,UAAU;IAC7E,OAAQ,CAA8B,EAAE,sBAAsB,KAAK,UAAU,CAAC;AAE/E;;;;GAIG;AACI,MAAM,kBAAkB,GAAG,CAAC,CAAU,EAAoC,EAAE,CAClF,OAAQ,CAA0C,EAAE,eAAe,KAAK,QAAQ,CAAC;AADrE,QAAA,kBAAkB,sBACmD;AAElF;;;;GAIG;AACH,SAAgB,YAAY,CAAC,KAAc;IAC1C,OAAO,CACN,OAAQ,KAAkC,EAAE,SAAS,KAAK,QAAQ;QAClE,OAAQ,KAAkC,EAAE,OAAO,KAAK,QAAQ;QAChE,IAAA,0BAAkB,EAAC,KAAK,CAAC;QACzB,yBAAyB,CAAC,KAAK,CAAC,CAChC,CAAC;AACH,CAAC;AAPD,oCAOC;AAED;;;;GAIG;AACH,SAAgB,2BAA2B,CAC1C,KAAc;IAEd,OAAO,YAAY,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,SAAS,KAAK,0BAAe,CAAC,yBAAyB,CAAC;AAC7F,CAAC;AAJD,kEAIC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { ITelemetryBaseProperties } from \"@fluidframework/core-interfaces\";\nimport {\n\tFluidErrorTypes,\n\ttype ILayerIncompatibilityError,\n} from \"@fluidframework/core-interfaces/internal\";\n\nimport type { ITelemetryPropertiesExt } from \"./telemetryTypes.js\";\n\n/**\n * An error emitted by the Fluid Framework.\n *\n * @remarks\n *\n * All normalized errors flowing through the Fluid Framework adhere to this readonly interface.\n *\n * It features the members of {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error | Error}\n * made readonly, as well as {@link IFluidErrorBase.errorType} and {@link IFluidErrorBase.errorInstanceId}.\n * It also features getters and setters for telemetry props to be included when the error is logged.\n *\n * @internal\n */\nexport interface IFluidErrorBase extends Error {\n\t/**\n\t * Classification of what type of error this is.\n\t *\n\t * @remarks Used programmatically by consumers to interpret the error.\n\t */\n\treadonly errorType: string;\n\n\t/**\n\t * Error's message property, made readonly.\n\t *\n\t * @remarks\n\t *\n\t * Recommendations:\n\t *\n\t * Be specific, but also take care when including variable data to consider suitability for aggregation in telemetry.\n\t * Also avoid including any data that jeopardizes the user's privacy. Add a tagged telemetry property instead.\n\t */\n\treadonly message: string;\n\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/stack}.\n\t */\n\treadonly stack?: string;\n\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/name}.\n\t */\n\treadonly name: string;\n\n\t/**\n\t * A Guid identifying this error instance.\n\t *\n\t * @remarks\n\t *\n\t * Useful in telemetry for deduplicating multiple logging events arising from the same error,\n\t * or correlating an error with an inner error that caused it, in case of error wrapping.\n\t */\n\treadonly errorInstanceId: string;\n\n\t/**\n\t * When present, inner error that caused this error.\n\t *\n\t * @remarks\n\t * This will often be an {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error|Error}, but could be any type.\n\t *\n\t * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause\n\t *\n\t * @privateRemarks\n\t * The \"cause\" field is added in ES2022. Using it even without that built-in support, is still helpful.\n\t * TODO: remove this declaration (use `Error.cause` property) when targeting ES2022 lib or later.\n\t */\n\tcause?: unknown;\n\n\t/**\n\t * Get the telemetry properties stashed on this error for logging.\n\t */\n\tgetTelemetryProperties(): ITelemetryBaseProperties;\n\n\t/**\n\t * Add telemetry properties to this error which will be logged with the error\n\t */\n\taddTelemetryProperties: (props: ITelemetryPropertiesExt) => void;\n}\n\nconst hasTelemetryPropFunctions = (x: unknown): boolean =>\n\ttypeof (x as Partial<IFluidErrorBase>)?.getTelemetryProperties === \"function\" &&\n\ttypeof (x as Partial<IFluidErrorBase>)?.addTelemetryProperties === \"function\";\n\n/**\n * Type guard for error data containing the {@link IFluidErrorBase.errorInstanceId} property.\n *\n * @internal\n */\nexport const hasErrorInstanceId = (x: unknown): x is { errorInstanceId: string } =>\n\ttypeof (x as Partial<{ errorInstanceId: string }>)?.errorInstanceId === \"string\";\n\n/**\n * Type guard for {@link IFluidErrorBase}.\n *\n * @internal\n */\nexport function isFluidError(error: unknown): error is IFluidErrorBase {\n\treturn (\n\t\ttypeof (error as Partial<IFluidErrorBase>)?.errorType === \"string\" &&\n\t\ttypeof (error as Partial<IFluidErrorBase>)?.message === \"string\" &&\n\t\thasErrorInstanceId(error) &&\n\t\thasTelemetryPropFunctions(error)\n\t);\n}\n\n/**\n * Helper that returns whether the provided error is a layer incompatibility error.\n *\n * @internal\n */\nexport function isLayerIncompatibilityError(\n\terror: unknown,\n): error is ILayerIncompatibilityError {\n\treturn isFluidError(error) && error.errorType === FluidErrorTypes.layerIncompatibilityError;\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -15,5 +15,5 @@ export { SampledTelemetryHelper, type CustomMetrics, type ICustomData, type Meas
|
|
|
15
15
|
export { createSampledLogger, type IEventSampler, type ISampledTelemetryLogger, measure, } from "./utils.js";
|
|
16
16
|
export type { TelemetryEventPropertyTypeExt, ITelemetryEventExt, ITelemetryGenericEventExt, ITelemetryErrorEventExt, ITelemetryPerformanceEventExt, ITelemetryLoggerExt, ITelemetryPropertiesExt, TelemetryEventCategory, } from "./telemetryTypes.js";
|
|
17
17
|
export { TelemetryEventBatcher } from "./telemetryEventBatcher.js";
|
|
18
|
-
export { validateLayerCompatibility } from "./layerCompatError.js";
|
|
18
|
+
export { allowIncompatibleLayersKey, validateLayerCompatibility } from "./layerCompatError.js";
|
|
19
19
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,4BAA4B,EAC5B,KAAK,iBAAiB,EACtB,4BAA4B,EAC5B,sBAAsB,EACtB,KAAK,eAAe,EACpB,yBAAyB,EACzB,8BAA8B,EAC9B,6BAA6B,EAC7B,KAAK,mBAAmB,GACxB,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,mBAAmB,EACnB,mBAAmB,EACnB,gCAAgC,EAChC,YAAY,EACZ,UAAU,EACV,oBAAoB,EACpB,yBAAyB,GACzB,MAAM,YAAY,CAAC;AACpB,OAAO,EACN,6BAA6B,EAC7B,sBAAsB,EACtB,aAAa,EACb,mBAAmB,EACnB,KAAK,sBAAsB,EAC3B,eAAe,EACf,eAAe,EACf,8BAA8B,EAC9B,YAAY,EACZ,qBAAqB,EACrB,cAAc,EACd,cAAc,EACd,SAAS,EACT,eAAe,GACf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,6BAA6B,EAAE,MAAM,oCAAoC,CAAC;AACnF,OAAO,EACN,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,GACd,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,kBAAkB,EAClB,KAAK,eAAe,EACpB,YAAY,EACZ,2BAA2B,GAC3B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,UAAU,EACV,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,EACjC,KAAK,yBAAyB,EAC9B,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,OAAO,EACP,gBAAgB,EAChB,gBAAgB,EAChB,KAAK,2BAA2B,GAChC,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,mBAAmB,EACnB,KAAK,cAAc,EACnB,UAAU,GACV,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EACN,sBAAsB,EACtB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,iBAAiB,GACtB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACN,mBAAmB,EACnB,KAAK,aAAa,EAClB,KAAK,uBAAuB,EAC5B,OAAO,GACP,MAAM,YAAY,CAAC;AACpB,YAAY,EACX,6BAA6B,EAC7B,kBAAkB,EAClB,yBAAyB,EACzB,uBAAuB,EACvB,6BAA6B,EAC7B,mBAAmB,EACnB,uBAAuB,EACvB,sBAAsB,GACtB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,4BAA4B,EAC5B,KAAK,iBAAiB,EACtB,4BAA4B,EAC5B,sBAAsB,EACtB,KAAK,eAAe,EACpB,yBAAyB,EACzB,8BAA8B,EAC9B,6BAA6B,EAC7B,KAAK,mBAAmB,GACxB,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,mBAAmB,EACnB,mBAAmB,EACnB,gCAAgC,EAChC,YAAY,EACZ,UAAU,EACV,oBAAoB,EACpB,yBAAyB,GACzB,MAAM,YAAY,CAAC;AACpB,OAAO,EACN,6BAA6B,EAC7B,sBAAsB,EACtB,aAAa,EACb,mBAAmB,EACnB,KAAK,sBAAsB,EAC3B,eAAe,EACf,eAAe,EACf,8BAA8B,EAC9B,YAAY,EACZ,qBAAqB,EACrB,cAAc,EACd,cAAc,EACd,SAAS,EACT,eAAe,GACf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,6BAA6B,EAAE,MAAM,oCAAoC,CAAC;AACnF,OAAO,EACN,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,GACd,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,kBAAkB,EAClB,KAAK,eAAe,EACpB,YAAY,EACZ,2BAA2B,GAC3B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,UAAU,EACV,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,EACjC,KAAK,yBAAyB,EAC9B,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,OAAO,EACP,gBAAgB,EAChB,gBAAgB,EAChB,KAAK,2BAA2B,GAChC,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,mBAAmB,EACnB,KAAK,cAAc,EACnB,UAAU,GACV,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EACN,sBAAsB,EACtB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,iBAAiB,GACtB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACN,mBAAmB,EACnB,KAAK,aAAa,EAClB,KAAK,uBAAuB,EAC5B,OAAO,GACP,MAAM,YAAY,CAAC;AACpB,YAAY,EACX,6BAA6B,EAC7B,kBAAkB,EAClB,yBAAyB,EACzB,uBAAuB,EACvB,6BAA6B,EAC7B,mBAAmB,EACnB,uBAAuB,EACvB,sBAAsB,GACtB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,0BAA0B,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.measure = exports.createSampledLogger = exports.SampledTelemetryHelper = exports.ThresholdCounter = exports.MockLogger = exports.createMockLoggerExt = exports.TelemetryDataTag = exports.tagCodeArtifacts = exports.tagData = exports.TaggedLoggerAdapter = exports.PerformanceEvent = exports.numberFromString = exports.formatTick = exports.createMultiSinkLogger = exports.createChildLogger = exports.eventNamespaceSeparator = exports.isLayerIncompatibilityError = exports.isFluidError = exports.hasErrorInstanceId = exports.safeRaiseEvent = exports.raiseConnectedEvent = exports.disconnectedEventName = exports.connectedEventName = exports.EventEmitterWithErrorHandling = exports.wrapErrorAndLog = exports.wrapError = exports.overwriteStack = exports.normalizeError = exports.NORMALIZED_ERROR_TYPE = exports.LoggingError = exports.isTaggedTelemetryPropertyValue = exports.isILoggingError = exports.isExternalError = exports.getCircularReplacer = exports.generateStack = exports.generateErrorWithStack = exports.extractLogSafeErrorProperties = exports.LayerIncompatibilityError = exports.validatePrecondition = exports.UsageError = exports.GenericError = exports.extractSafePropertiesFromMessage = exports.DataProcessingError = exports.DataCorruptionError = exports.createConfigBasedOptionsProxy = exports.wrapConfigProviderWithDefaults = exports.loggerToMonitoringContext = exports.mixinMonitoringContext = exports.sessionStorageConfigProvider = exports.createChildMonitoringContext = void 0;
|
|
8
|
-
exports.validateLayerCompatibility = exports.TelemetryEventBatcher = void 0;
|
|
8
|
+
exports.validateLayerCompatibility = exports.allowIncompatibleLayersKey = exports.TelemetryEventBatcher = void 0;
|
|
9
9
|
var config_js_1 = require("./config.js");
|
|
10
10
|
Object.defineProperty(exports, "createChildMonitoringContext", { enumerable: true, get: function () { return config_js_1.createChildMonitoringContext; } });
|
|
11
11
|
Object.defineProperty(exports, "sessionStorageConfigProvider", { enumerable: true, get: function () { return config_js_1.sessionStorageConfigProvider; } });
|
|
@@ -70,5 +70,6 @@ Object.defineProperty(exports, "measure", { enumerable: true, get: function () {
|
|
|
70
70
|
var telemetryEventBatcher_js_1 = require("./telemetryEventBatcher.js");
|
|
71
71
|
Object.defineProperty(exports, "TelemetryEventBatcher", { enumerable: true, get: function () { return telemetryEventBatcher_js_1.TelemetryEventBatcher; } });
|
|
72
72
|
var layerCompatError_js_1 = require("./layerCompatError.js");
|
|
73
|
+
Object.defineProperty(exports, "allowIncompatibleLayersKey", { enumerable: true, get: function () { return layerCompatError_js_1.allowIncompatibleLayersKey; } });
|
|
73
74
|
Object.defineProperty(exports, "validateLayerCompatibility", { enumerable: true, get: function () { return layerCompatError_js_1.validateLayerCompatibility; } });
|
|
74
75
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;AAEH,yCAUqB;AATpB,yHAAA,4BAA4B,OAAA;AAE5B,yHAAA,4BAA4B,OAAA;AAC5B,mHAAA,sBAAsB,OAAA;AAEtB,sHAAA,yBAAyB,OAAA;AACzB,2HAAA,8BAA8B,OAAA;AAC9B,0HAAA,6BAA6B,OAAA;AAG9B,uCAQoB;AAPnB,+GAAA,mBAAmB,OAAA;AACnB,+GAAA,mBAAmB,OAAA;AACnB,4HAAA,gCAAgC,OAAA;AAChC,wGAAA,YAAY,OAAA;AACZ,sGAAA,UAAU,OAAA;AACV,gHAAA,oBAAoB,OAAA;AACpB,qHAAA,yBAAyB,OAAA;AAE1B,qDAe2B;AAd1B,gIAAA,6BAA6B,OAAA;AAC7B,yHAAA,sBAAsB,OAAA;AACtB,gHAAA,aAAa,OAAA;AACb,sHAAA,mBAAmB,OAAA;AAEnB,kHAAA,eAAe,OAAA;AACf,kHAAA,eAAe,OAAA;AACf,iIAAA,8BAA8B,OAAA;AAC9B,+GAAA,YAAY,OAAA;AACZ,wHAAA,qBAAqB,OAAA;AACrB,iHAAA,cAAc,OAAA;AACd,iHAAA,cAAc,OAAA;AACd,4GAAA,SAAS,OAAA;AACT,kHAAA,eAAe,OAAA;AAEhB,uFAAmF;AAA1E,iJAAA,6BAA6B,OAAA;AACtC,yCAKqB;AAJpB,+GAAA,kBAAkB,OAAA;AAClB,kHAAA,qBAAqB,OAAA;AACrB,gHAAA,mBAAmB,OAAA;AACnB,2GAAA,cAAc,OAAA;AAEf,yDAK6B;AAJ5B,uHAAA,kBAAkB,OAAA;AAElB,iHAAA,YAAY,OAAA;AACZ,gIAAA,2BAA2B,OAAA;AAE5B,yCAgBqB;AAfpB,oHAAA,uBAAuB,OAAA;AACvB,8GAAA,iBAAiB,OAAA;AACjB,kHAAA,qBAAqB,OAAA;AACrB,uGAAA,UAAU,OAAA;AAKV,6GAAA,gBAAgB,OAAA;AAChB,6GAAA,gBAAgB,OAAA;AAChB,gHAAA,mBAAmB,OAAA;AACnB,oGAAA,OAAO,OAAA;AACP,6GAAA,gBAAgB,OAAA;AAChB,6GAAA,gBAAgB,OAAA;AAGjB,iDAIyB;AAHxB,oHAAA,mBAAmB,OAAA;AAEnB,2GAAA,UAAU,OAAA;AAEX,6DAAyD;AAAhD,uHAAA,gBAAgB,OAAA;AACzB,yEAKqC;AAJpC,mIAAA,sBAAsB,OAAA;AAKvB,uCAKoB;AAJnB,+GAAA,mBAAmB,OAAA;AAGnB,mGAAA,OAAO,OAAA;AAYR,uEAAmE;AAA1D,iIAAA,qBAAqB,OAAA;AAC9B,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;AAEH,yCAUqB;AATpB,yHAAA,4BAA4B,OAAA;AAE5B,yHAAA,4BAA4B,OAAA;AAC5B,mHAAA,sBAAsB,OAAA;AAEtB,sHAAA,yBAAyB,OAAA;AACzB,2HAAA,8BAA8B,OAAA;AAC9B,0HAAA,6BAA6B,OAAA;AAG9B,uCAQoB;AAPnB,+GAAA,mBAAmB,OAAA;AACnB,+GAAA,mBAAmB,OAAA;AACnB,4HAAA,gCAAgC,OAAA;AAChC,wGAAA,YAAY,OAAA;AACZ,sGAAA,UAAU,OAAA;AACV,gHAAA,oBAAoB,OAAA;AACpB,qHAAA,yBAAyB,OAAA;AAE1B,qDAe2B;AAd1B,gIAAA,6BAA6B,OAAA;AAC7B,yHAAA,sBAAsB,OAAA;AACtB,gHAAA,aAAa,OAAA;AACb,sHAAA,mBAAmB,OAAA;AAEnB,kHAAA,eAAe,OAAA;AACf,kHAAA,eAAe,OAAA;AACf,iIAAA,8BAA8B,OAAA;AAC9B,+GAAA,YAAY,OAAA;AACZ,wHAAA,qBAAqB,OAAA;AACrB,iHAAA,cAAc,OAAA;AACd,iHAAA,cAAc,OAAA;AACd,4GAAA,SAAS,OAAA;AACT,kHAAA,eAAe,OAAA;AAEhB,uFAAmF;AAA1E,iJAAA,6BAA6B,OAAA;AACtC,yCAKqB;AAJpB,+GAAA,kBAAkB,OAAA;AAClB,kHAAA,qBAAqB,OAAA;AACrB,gHAAA,mBAAmB,OAAA;AACnB,2GAAA,cAAc,OAAA;AAEf,yDAK6B;AAJ5B,uHAAA,kBAAkB,OAAA;AAElB,iHAAA,YAAY,OAAA;AACZ,gIAAA,2BAA2B,OAAA;AAE5B,yCAgBqB;AAfpB,oHAAA,uBAAuB,OAAA;AACvB,8GAAA,iBAAiB,OAAA;AACjB,kHAAA,qBAAqB,OAAA;AACrB,uGAAA,UAAU,OAAA;AAKV,6GAAA,gBAAgB,OAAA;AAChB,6GAAA,gBAAgB,OAAA;AAChB,gHAAA,mBAAmB,OAAA;AACnB,oGAAA,OAAO,OAAA;AACP,6GAAA,gBAAgB,OAAA;AAChB,6GAAA,gBAAgB,OAAA;AAGjB,iDAIyB;AAHxB,oHAAA,mBAAmB,OAAA;AAEnB,2GAAA,UAAU,OAAA;AAEX,6DAAyD;AAAhD,uHAAA,gBAAgB,OAAA;AACzB,yEAKqC;AAJpC,mIAAA,sBAAsB,OAAA;AAKvB,uCAKoB;AAJnB,+GAAA,mBAAmB,OAAA;AAGnB,mGAAA,OAAO,OAAA;AAYR,uEAAmE;AAA1D,iIAAA,qBAAqB,OAAA;AAC9B,6DAA+F;AAAtF,iIAAA,0BAA0B,OAAA;AAAE,iIAAA,0BAA0B,OAAA","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport {\n\tcreateChildMonitoringContext,\n\ttype MonitoringContext,\n\tsessionStorageConfigProvider,\n\tmixinMonitoringContext,\n\ttype IConfigProvider,\n\tloggerToMonitoringContext,\n\twrapConfigProviderWithDefaults,\n\tcreateConfigBasedOptionsProxy,\n\ttype OptionConfigReaders,\n} from \"./config.js\";\nexport {\n\tDataCorruptionError,\n\tDataProcessingError,\n\textractSafePropertiesFromMessage,\n\tGenericError,\n\tUsageError,\n\tvalidatePrecondition,\n\tLayerIncompatibilityError,\n} from \"./error.js\";\nexport {\n\textractLogSafeErrorProperties,\n\tgenerateErrorWithStack,\n\tgenerateStack,\n\tgetCircularReplacer,\n\ttype IFluidErrorAnnotations,\n\tisExternalError,\n\tisILoggingError,\n\tisTaggedTelemetryPropertyValue,\n\tLoggingError,\n\tNORMALIZED_ERROR_TYPE,\n\tnormalizeError,\n\toverwriteStack,\n\twrapError,\n\twrapErrorAndLog,\n} from \"./errorLogging.js\";\nexport { EventEmitterWithErrorHandling } from \"./eventEmitterWithErrorHandling.js\";\nexport {\n\tconnectedEventName,\n\tdisconnectedEventName,\n\traiseConnectedEvent,\n\tsafeRaiseEvent,\n} from \"./events.js\";\nexport {\n\thasErrorInstanceId,\n\ttype IFluidErrorBase,\n\tisFluidError,\n\tisLayerIncompatibilityError,\n} from \"./fluidErrorBase.js\";\nexport {\n\teventNamespaceSeparator,\n\tcreateChildLogger,\n\tcreateMultiSinkLogger,\n\tformatTick,\n\ttype IPerformanceEventMarkers,\n\ttype ITelemetryLoggerPropertyBag,\n\ttype ITelemetryLoggerPropertyBags,\n\ttype MultiSinkLoggerProperties,\n\tnumberFromString,\n\tPerformanceEvent,\n\tTaggedLoggerAdapter,\n\ttagData,\n\ttagCodeArtifacts,\n\tTelemetryDataTag,\n\ttype TelemetryEventPropertyTypes,\n} from \"./logger.js\";\nexport {\n\tcreateMockLoggerExt,\n\ttype IMockLoggerExt,\n\tMockLogger,\n} from \"./mockLogger.js\";\nexport { ThresholdCounter } from \"./thresholdCounter.js\";\nexport {\n\tSampledTelemetryHelper,\n\ttype CustomMetrics,\n\ttype ICustomData,\n\ttype MeasureReturnType,\n} from \"./sampledTelemetryHelper.js\";\nexport {\n\tcreateSampledLogger,\n\ttype IEventSampler,\n\ttype ISampledTelemetryLogger,\n\tmeasure,\n} from \"./utils.js\";\nexport type {\n\tTelemetryEventPropertyTypeExt,\n\tITelemetryEventExt,\n\tITelemetryGenericEventExt,\n\tITelemetryErrorEventExt,\n\tITelemetryPerformanceEventExt,\n\tITelemetryLoggerExt,\n\tITelemetryPropertiesExt,\n\tTelemetryEventCategory,\n} from \"./telemetryTypes.js\";\nexport { TelemetryEventBatcher } from \"./telemetryEventBatcher.js\";\nexport { allowIncompatibleLayersKey, validateLayerCompatibility } from \"./layerCompatError.js\";\n"]}
|
|
@@ -4,13 +4,31 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { type FluidLayer, type ILayerCompatDetails, type ILayerCompatSupportRequirements } from "@fluid-internal/client-utils";
|
|
6
6
|
import type { IErrorBase } from "@fluidframework/core-interfaces";
|
|
7
|
-
import type {
|
|
7
|
+
import type { MonitoringContext } from "./config.js";
|
|
8
|
+
/**
|
|
9
|
+
* The config key to disable layer compatibility validation.
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
export declare const allowIncompatibleLayersKey = "Fluid.AllowIncompatibleLayers";
|
|
8
13
|
/**
|
|
9
14
|
* Validates the compatibility between two layers using their compatibility details and support requirements.
|
|
10
|
-
* If the layers are incompatible, it logs
|
|
15
|
+
* If the layers are incompatible, it logs a "LayerIncompatibilityError" error event. It will also call the dispose
|
|
11
16
|
* function with the error and throw the error.
|
|
17
|
+
* @param layer1 - The name of the first layer.
|
|
18
|
+
* @param layer2 - The name of the second layer.
|
|
19
|
+
* @param compatDetailsLayer1 - The compatibility details of the first layer.
|
|
20
|
+
* @param compatSupportRequirementsLayer1 - The support requirements that the second layer must meet to be compatible
|
|
21
|
+
* with the first layer.
|
|
22
|
+
* @param maybeCompatDetailsLayer2 - The compatibility details of the second layer. This can be undefined if the
|
|
23
|
+
* second layer does not provide compatibility details.
|
|
24
|
+
* @param disposeFn - A function that will be called with the error if the layers are incompatible.
|
|
25
|
+
* @param mc - The monitoring context for logging and reading configuration.
|
|
26
|
+
* @param strictCompatibilityCheck - If true, the function will use default compatibility details for the second layer if
|
|
27
|
+
* they are missing and use it for validation.
|
|
28
|
+
* If false, it will skip the compatibility check if the details are missing and just log an error.
|
|
29
|
+
* Defaults to false.
|
|
12
30
|
*
|
|
13
31
|
* @internal
|
|
14
32
|
*/
|
|
15
|
-
export declare function validateLayerCompatibility(layer1: FluidLayer, layer2: FluidLayer, compatDetailsLayer1: Pick<ILayerCompatDetails, "pkgVersion" | "generation">, compatSupportRequirementsLayer1: ILayerCompatSupportRequirements, maybeCompatDetailsLayer2: ILayerCompatDetails | undefined, disposeFn: (error?: IErrorBase) => void,
|
|
33
|
+
export declare function validateLayerCompatibility(layer1: FluidLayer, layer2: FluidLayer, compatDetailsLayer1: Pick<ILayerCompatDetails, "pkgVersion" | "generation">, compatSupportRequirementsLayer1: ILayerCompatSupportRequirements, maybeCompatDetailsLayer2: ILayerCompatDetails | undefined, disposeFn: (error?: IErrorBase) => void, mc: MonitoringContext, strictCompatibilityCheck?: boolean): void;
|
|
16
34
|
//# sourceMappingURL=layerCompatError.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layerCompatError.d.ts","sourceRoot":"","sources":["../src/layerCompatError.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAEN,KAAK,UAAU,EACf,KAAK,mBAAmB,EACxB,KAAK,+BAA+B,EACpC,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"layerCompatError.d.ts","sourceRoot":"","sources":["../src/layerCompatError.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAEN,KAAK,UAAU,EACf,KAAK,mBAAmB,EACxB,KAAK,+BAA+B,EACpC,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAElE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGrD;;;GAGG;AACH,eAAO,MAAM,0BAA0B,kCAAkC,CAAC;AAe1E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,0BAA0B,CACzC,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,UAAU,EAClB,mBAAmB,EAAE,IAAI,CAAC,mBAAmB,EAAE,YAAY,GAAG,YAAY,CAAC,EAC3E,+BAA+B,EAAE,+BAA+B,EAChE,wBAAwB,EAAE,mBAAmB,GAAG,SAAS,EACzD,SAAS,EAAE,CAAC,KAAK,CAAC,EAAE,UAAU,KAAK,IAAI,EACvC,EAAE,EAAE,iBAAiB,EACrB,wBAAwB,GAAE,OAAe,GACvC,IAAI,CAiFN"}
|
package/dist/layerCompatError.js
CHANGED
|
@@ -4,17 +4,46 @@
|
|
|
4
4
|
* Licensed under the MIT License.
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.validateLayerCompatibility = void 0;
|
|
7
|
+
exports.validateLayerCompatibility = exports.allowIncompatibleLayersKey = void 0;
|
|
8
8
|
const client_utils_1 = require("@fluid-internal/client-utils");
|
|
9
9
|
const error_js_1 = require("./error.js");
|
|
10
|
+
/**
|
|
11
|
+
* The config key to disable layer compatibility validation.
|
|
12
|
+
* @internal
|
|
13
|
+
*/
|
|
14
|
+
exports.allowIncompatibleLayersKey = "Fluid.AllowIncompatibleLayers";
|
|
15
|
+
/**
|
|
16
|
+
* Tracks whether the event is logged when failing on layer incompatibility is bypassed via global config.
|
|
17
|
+
* This is used to ensure that the bypass event is only logged once per session so it does not flood telemetry.
|
|
18
|
+
*/
|
|
19
|
+
let globalBypassLogged = false;
|
|
20
|
+
/**
|
|
21
|
+
* Tracks whether the event is logged when failing on layer incompatibility is bypassed due to missing
|
|
22
|
+
* compatibility details for each layer pair.
|
|
23
|
+
* This is used to ensure that the bypass event is only logged once per layer pair so it does not flood telemetry.
|
|
24
|
+
*/
|
|
25
|
+
const strictCheckBypassLoggedForPair = new Set();
|
|
10
26
|
/**
|
|
11
27
|
* Validates the compatibility between two layers using their compatibility details and support requirements.
|
|
12
|
-
* If the layers are incompatible, it logs
|
|
28
|
+
* If the layers are incompatible, it logs a "LayerIncompatibilityError" error event. It will also call the dispose
|
|
13
29
|
* function with the error and throw the error.
|
|
30
|
+
* @param layer1 - The name of the first layer.
|
|
31
|
+
* @param layer2 - The name of the second layer.
|
|
32
|
+
* @param compatDetailsLayer1 - The compatibility details of the first layer.
|
|
33
|
+
* @param compatSupportRequirementsLayer1 - The support requirements that the second layer must meet to be compatible
|
|
34
|
+
* with the first layer.
|
|
35
|
+
* @param maybeCompatDetailsLayer2 - The compatibility details of the second layer. This can be undefined if the
|
|
36
|
+
* second layer does not provide compatibility details.
|
|
37
|
+
* @param disposeFn - A function that will be called with the error if the layers are incompatible.
|
|
38
|
+
* @param mc - The monitoring context for logging and reading configuration.
|
|
39
|
+
* @param strictCompatibilityCheck - If true, the function will use default compatibility details for the second layer if
|
|
40
|
+
* they are missing and use it for validation.
|
|
41
|
+
* If false, it will skip the compatibility check if the details are missing and just log an error.
|
|
42
|
+
* Defaults to false.
|
|
14
43
|
*
|
|
15
44
|
* @internal
|
|
16
45
|
*/
|
|
17
|
-
function validateLayerCompatibility(layer1, layer2, compatDetailsLayer1, compatSupportRequirementsLayer1, maybeCompatDetailsLayer2, disposeFn,
|
|
46
|
+
function validateLayerCompatibility(layer1, layer2, compatDetailsLayer1, compatSupportRequirementsLayer1, maybeCompatDetailsLayer2, disposeFn, mc, strictCompatibilityCheck = false) {
|
|
18
47
|
const layerCheckResult = (0, client_utils_1.checkLayerCompatibility)(compatSupportRequirementsLayer1, maybeCompatDetailsLayer2);
|
|
19
48
|
if (!layerCheckResult.isCompatible) {
|
|
20
49
|
const coreProperties = {
|
|
@@ -37,7 +66,38 @@ function validateLayerCompatibility(layer1, layer2, compatDetailsLayer1, compatS
|
|
|
37
66
|
...coreProperties,
|
|
38
67
|
details: JSON.stringify(detailedProperties),
|
|
39
68
|
});
|
|
40
|
-
|
|
69
|
+
if (mc.config.getBoolean(exports.allowIncompatibleLayersKey) === true) {
|
|
70
|
+
// If the validation is explicitly disabled via config, do not fail. This config provides a way to bypass
|
|
71
|
+
// compatibility validation while this feature is being rolled out.
|
|
72
|
+
if (!globalBypassLogged) {
|
|
73
|
+
// This event is only logged once per session to avoid flooding telemetry.
|
|
74
|
+
globalBypassLogged = true;
|
|
75
|
+
mc.logger.sendTelemetryEvent({
|
|
76
|
+
eventName: "LayerIncompatibilityDetectedButBypassed",
|
|
77
|
+
reason: `${exports.allowIncompatibleLayersKey} config is set to true`,
|
|
78
|
+
}, error);
|
|
79
|
+
}
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
if (maybeCompatDetailsLayer2 === undefined && !strictCompatibilityCheck) {
|
|
83
|
+
// If there is no compatibility details for layer2 and strictCompatibilityCheck is false, do not fail.
|
|
84
|
+
// There can be a couple of scenarios where this can happen:
|
|
85
|
+
// 1. layer2's version is older than the version where compatibility enforcement was introduced. In this
|
|
86
|
+
// case, the behavior is the same as before compatibility enforcement was introduced.
|
|
87
|
+
// 2. layer2 has a custom implementation which doesn't provide compatibility details. In this case,
|
|
88
|
+
// we don't know for sure that it is incompatible. It may fail at a later point when it tries to use
|
|
89
|
+
// some feature that the Runtime doesn't support.
|
|
90
|
+
if (!strictCheckBypassLoggedForPair.has(`${layer1}-${layer2}`)) {
|
|
91
|
+
// This event is only logged once per session per layer combination to avoid flooding telemetry.
|
|
92
|
+
strictCheckBypassLoggedForPair.add(`${layer1}-${layer2}`);
|
|
93
|
+
mc.logger.sendTelemetryEvent({
|
|
94
|
+
eventName: "LayerIncompatibilityDetectedButBypassed",
|
|
95
|
+
reason: `No compatibility details provided for ${layer2} and strictCompatibilityCheck is false`,
|
|
96
|
+
}, error);
|
|
97
|
+
}
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
mc.logger.sendErrorEvent({
|
|
41
101
|
eventName: "LayerIncompatibilityError",
|
|
42
102
|
}, error);
|
|
43
103
|
disposeFn(error);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layerCompatError.js","sourceRoot":"","sources":["../src/layerCompatError.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,+DAKsC;
|
|
1
|
+
{"version":3,"file":"layerCompatError.js","sourceRoot":"","sources":["../src/layerCompatError.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tcheckLayerCompatibility,\n\ttype FluidLayer,\n\ttype ILayerCompatDetails,\n\ttype ILayerCompatSupportRequirements,\n} from \"@fluid-internal/client-utils\";\nimport type { IErrorBase } from \"@fluidframework/core-interfaces\";\n\nimport type { MonitoringContext } from \"./config.js\";\nimport { LayerIncompatibilityError } from \"./error.js\";\n\n/**\n * The config key to disable layer compatibility validation.\n * @internal\n */\nexport const allowIncompatibleLayersKey = \"Fluid.AllowIncompatibleLayers\";\n\n/**\n * Tracks whether the event is logged when failing on layer incompatibility is bypassed via global config.\n * This is used to ensure that the bypass event is only logged once per session so it does not flood telemetry.\n */\nlet globalBypassLogged = false;\n\n/**\n * Tracks whether the event is logged when failing on layer incompatibility is bypassed due to missing\n * compatibility details for each layer pair.\n * This is used to ensure that the bypass event is only logged once per layer pair so it does not flood telemetry.\n */\nconst strictCheckBypassLoggedForPair: Set<string> = new Set<string>();\n\n/**\n * Validates the compatibility between two layers using their compatibility details and support requirements.\n * If the layers are incompatible, it logs a \"LayerIncompatibilityError\" error event. It will also call the dispose\n * function with the error and throw the error.\n * @param layer1 - The name of the first layer.\n * @param layer2 - The name of the second layer.\n * @param compatDetailsLayer1 - The compatibility details of the first layer.\n * @param compatSupportRequirementsLayer1 - The support requirements that the second layer must meet to be compatible\n * with the first layer.\n * @param maybeCompatDetailsLayer2 - The compatibility details of the second layer. This can be undefined if the\n * second layer does not provide compatibility details.\n * @param disposeFn - A function that will be called with the error if the layers are incompatible.\n * @param mc - The monitoring context for logging and reading configuration.\n * @param strictCompatibilityCheck - If true, the function will use default compatibility details for the second layer if\n * they are missing and use it for validation.\n * If false, it will skip the compatibility check if the details are missing and just log an error.\n * Defaults to false.\n *\n * @internal\n */\nexport function validateLayerCompatibility(\n\tlayer1: FluidLayer,\n\tlayer2: FluidLayer,\n\tcompatDetailsLayer1: Pick<ILayerCompatDetails, \"pkgVersion\" | \"generation\">,\n\tcompatSupportRequirementsLayer1: ILayerCompatSupportRequirements,\n\tmaybeCompatDetailsLayer2: ILayerCompatDetails | undefined,\n\tdisposeFn: (error?: IErrorBase) => void,\n\tmc: MonitoringContext,\n\tstrictCompatibilityCheck: boolean = false,\n): void {\n\tconst layerCheckResult = checkLayerCompatibility(\n\t\tcompatSupportRequirementsLayer1,\n\t\tmaybeCompatDetailsLayer2,\n\t);\n\tif (!layerCheckResult.isCompatible) {\n\t\tconst coreProperties = {\n\t\t\tlayer: layer1,\n\t\t\tincompatibleLayer: layer2,\n\t\t\tlayerVersion: compatDetailsLayer1.pkgVersion,\n\t\t\tincompatibleLayerVersion: maybeCompatDetailsLayer2?.pkgVersion ?? \"unknown\",\n\t\t\tcompatibilityRequirementsInMonths:\n\t\t\t\tcompatDetailsLayer1.generation -\n\t\t\t\tcompatSupportRequirementsLayer1.minSupportedGeneration,\n\t\t\tactualDifferenceInMonths:\n\t\t\t\tcompatDetailsLayer1.generation - (maybeCompatDetailsLayer2?.generation ?? 0),\n\t\t};\n\t\tconst detailedProperties = {\n\t\t\tlayerGeneration: compatDetailsLayer1.generation,\n\t\t\tincompatibleLayerGeneration: maybeCompatDetailsLayer2?.generation,\n\t\t\tminSupportedGeneration: compatSupportRequirementsLayer1.minSupportedGeneration,\n\t\t\tisGenerationCompatible: layerCheckResult.isGenerationCompatible,\n\t\t\tunsupportedFeatures: layerCheckResult.unsupportedFeatures,\n\t\t};\n\n\t\tconst error = new LayerIncompatibilityError(\n\t\t\t`The versions of the ${layer1} and ${layer2} are not compatible`,\n\t\t\t{\n\t\t\t\t...coreProperties,\n\t\t\t\tdetails: JSON.stringify(detailedProperties),\n\t\t\t},\n\t\t);\n\n\t\tif (mc.config.getBoolean(allowIncompatibleLayersKey) === true) {\n\t\t\t// If the validation is explicitly disabled via config, do not fail. This config provides a way to bypass\n\t\t\t// compatibility validation while this feature is being rolled out.\n\t\t\tif (!globalBypassLogged) {\n\t\t\t\t// This event is only logged once per session to avoid flooding telemetry.\n\t\t\t\tglobalBypassLogged = true;\n\t\t\t\tmc.logger.sendTelemetryEvent(\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"LayerIncompatibilityDetectedButBypassed\",\n\t\t\t\t\t\treason: `${allowIncompatibleLayersKey} config is set to true`,\n\t\t\t\t\t},\n\t\t\t\t\terror,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (maybeCompatDetailsLayer2 === undefined && !strictCompatibilityCheck) {\n\t\t\t// If there is no compatibility details for layer2 and strictCompatibilityCheck is false, do not fail.\n\t\t\t// There can be a couple of scenarios where this can happen:\n\t\t\t// 1. layer2's version is older than the version where compatibility enforcement was introduced. In this\n\t\t\t// case, the behavior is the same as before compatibility enforcement was introduced.\n\t\t\t// 2. layer2 has a custom implementation which doesn't provide compatibility details. In this case,\n\t\t\t// we don't know for sure that it is incompatible. It may fail at a later point when it tries to use\n\t\t\t// some feature that the Runtime doesn't support.\n\t\t\tif (!strictCheckBypassLoggedForPair.has(`${layer1}-${layer2}`)) {\n\t\t\t\t// This event is only logged once per session per layer combination to avoid flooding telemetry.\n\t\t\t\tstrictCheckBypassLoggedForPair.add(`${layer1}-${layer2}`);\n\t\t\t\tmc.logger.sendTelemetryEvent(\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"LayerIncompatibilityDetectedButBypassed\",\n\t\t\t\t\t\treason: `No compatibility details provided for ${layer2} and strictCompatibilityCheck is false`,\n\t\t\t\t\t},\n\t\t\t\t\terror,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tmc.logger.sendErrorEvent(\n\t\t\t{\n\t\t\t\teventName: \"LayerIncompatibilityError\",\n\t\t\t},\n\t\t\terror,\n\t\t);\n\t\tdisposeFn(error);\n\t\tthrow error;\n\t}\n}\n"]}
|
package/lib/error.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAC5F,OAAO,
|
|
1
|
+
{"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"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"}
|
package/lib/error.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
import { FluidErrorTypes,
|
|
5
|
+
import { FluidErrorTypes, } from "@fluidframework/core-interfaces/internal";
|
|
6
6
|
import { LoggingError, NORMALIZED_ERROR_TYPE, isExternalError, normalizeError, wrapError, } from "./errorLogging.js";
|
|
7
7
|
/**
|
|
8
8
|
* Throws a UsageError with the given message if the condition is not met.
|
|
@@ -158,7 +158,7 @@ export class LayerIncompatibilityError extends LoggingError {
|
|
|
158
158
|
...telemetryProps,
|
|
159
159
|
layerIncompatibilityError: true,
|
|
160
160
|
});
|
|
161
|
-
this.errorType =
|
|
161
|
+
this.errorType = FluidErrorTypes.layerIncompatibilityError;
|
|
162
162
|
this.layer = incompatibilityProps.layer;
|
|
163
163
|
this.layerVersion = incompatibilityProps.layerVersion;
|
|
164
164
|
this.incompatibleLayer = incompatibilityProps.incompatibleLayer;
|
package/lib/error.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { IErrorBase, ITelemetryBaseProperties } from \"@fluidframework/core-interfaces\";\nimport {\n\tFluidErrorTypes,\n\tFluidErrorTypesAlpha,\n\ttype IGenericError,\n\ttype ILayerIncompatibilityError,\n\ttype IUsageError,\n} from \"@fluidframework/core-interfaces/internal\";\nimport type { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\n\nimport {\n\tLoggingError,\n\tNORMALIZED_ERROR_TYPE,\n\tisExternalError,\n\tnormalizeError,\n\twrapError,\n} from \"./errorLogging.js\";\nimport type { IFluidErrorBase } from \"./fluidErrorBase.js\";\nimport type { ITelemetryPropertiesExt } from \"./telemetryTypes.js\";\n\n/**\n * Throws a UsageError with the given message if the condition is not met.\n * Use this API when `false` indicates a precondition is not met on a public API (for any FF layer).\n *\n * @param condition - The condition that should be true, if the condition is false a UsageError will be thrown.\n * @param message - The message to include in the error when the condition does not hold.\n * @param props - Telemetry props to include on the error when the condition does not hold.\n * @internal\n */\nexport function validatePrecondition(\n\tcondition: boolean,\n\tmessage: string,\n\tprops?: ITelemetryBaseProperties,\n): asserts condition {\n\tif (!condition) {\n\t\tthrow new UsageError(message, props);\n\t}\n}\n\n/**\n * Generic wrapper for an unrecognized/uncategorized error object\n *\n * @internal\n */\nexport class GenericError extends LoggingError implements IGenericError, IFluidErrorBase {\n\tpublic readonly errorType = FluidErrorTypes.genericError;\n\n\t/**\n\t * Create a new GenericError\n\t * @param message - Error message\n\t * @param error - inner error object\n\t * @param props - Telemetry props to include when the error is logged\n\t */\n\tpublic constructor(\n\t\tmessage: string,\n\t\t// TODO: Use `unknown` instead (API breaking change because error is not just an input parameter, but a public member of the class)\n\t\t// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any\n\t\tpublic readonly error?: any,\n\t\tprops?: ITelemetryBaseProperties,\n\t) {\n\t\t// Don't try to log the inner error\n\t\tsuper(message, props, new Set([\"error\"]));\n\t}\n}\n\n/**\n * Error indicating an API is being used improperly resulting in an invalid operation.\n *\n * @internal\n */\nexport class UsageError extends LoggingError implements IUsageError, IFluidErrorBase {\n\tpublic readonly errorType = FluidErrorTypes.usageError;\n\n\tpublic constructor(message: string, props?: ITelemetryBaseProperties) {\n\t\tsuper(message, { ...props, usageError: true });\n\t}\n}\n\n/**\n * DataCorruptionError indicates that we encountered definitive evidence that the data at rest\n * backing this container is corrupted, and this container would never be expected to load properly again\n *\n * @internal\n */\nexport class DataCorruptionError extends LoggingError implements IErrorBase, IFluidErrorBase {\n\tpublic readonly errorType = FluidErrorTypes.dataCorruptionError;\n\tpublic readonly canRetry = false;\n\n\tpublic constructor(message: string, props: ITelemetryBaseProperties) {\n\t\tsuper(message, { ...props, dataProcessingError: 1 });\n\t}\n}\n\n/**\n * Indicates we hit a fatal error while processing incoming data from the Fluid Service.\n *\n * @remarks\n *\n * The error will often originate in the dataStore or DDS implementation that is responding to incoming changes.\n * This differs from {@link DataCorruptionError} in that this may be a transient error that will not repro in another\n * client or session.\n *\n * @internal\n */\nexport class DataProcessingError extends LoggingError implements IErrorBase, IFluidErrorBase {\n\t/**\n\t * {@inheritDoc IFluidErrorBase.errorType}\n\t */\n\tpublic readonly errorType = FluidErrorTypes.dataProcessingError;\n\n\tpublic readonly canRetry = false;\n\n\tprivate constructor(errorMessage: string, props?: ITelemetryBaseProperties) {\n\t\tsuper(errorMessage, props);\n\t}\n\n\t/**\n\t * Create a new `DataProcessingError` detected and raised within the Fluid Framework.\n\t */\n\tpublic static create(\n\t\terrorMessage: string,\n\t\tdataProcessingCodepath: string,\n\t\tmessageLike?: Partial<\n\t\t\tPick<\n\t\t\t\tISequencedDocumentMessage,\n\t\t\t\t| \"clientId\"\n\t\t\t\t| \"sequenceNumber\"\n\t\t\t\t| \"clientSequenceNumber\"\n\t\t\t\t| \"referenceSequenceNumber\"\n\t\t\t\t| \"minimumSequenceNumber\"\n\t\t\t\t| \"timestamp\"\n\t\t\t>\n\t\t>,\n\t\tprops: ITelemetryPropertiesExt = {},\n\t\tstackTraceLimit?: number,\n\t): IFluidErrorBase {\n\t\tconst ErrorConfig = Error as unknown as { stackTraceLimit: number };\n\t\tconst originalStackTraceLimit = ErrorConfig.stackTraceLimit;\n\t\ttry {\n\t\t\tif (stackTraceLimit !== undefined) {\n\t\t\t\tErrorConfig.stackTraceLimit = stackTraceLimit;\n\t\t\t}\n\n\t\t\tconst dataProcessingError = DataProcessingError.wrapIfUnrecognized(\n\t\t\t\terrorMessage,\n\t\t\t\tdataProcessingCodepath,\n\t\t\t\tmessageLike,\n\t\t\t);\n\t\t\tdataProcessingError.addTelemetryProperties(props);\n\n\t\t\treturn dataProcessingError;\n\t\t} finally {\n\t\t\t// Reset the stack trace limit to the original value\n\t\t\tif (stackTraceLimit !== undefined) {\n\t\t\t\tErrorConfig.stackTraceLimit = originalStackTraceLimit;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Wrap the given error in a `DataProcessingError`, unless the error is already of a known type\n\t * with the exception of a normalized {@link LoggingError}, which will still be wrapped.\n\t *\n\t * In either case, the error will have some relevant properties added for telemetry.\n\t *\n\t * @remarks\n\t *\n\t * We wrap conditionally since known error types represent well-understood failure modes, and ideally\n\t * one day we will move away from throwing these errors but rather we'll return them.\n\t * But an unrecognized error needs to be classified as `DataProcessingError`.\n\t *\n\t * @param originalError - The error to be converted.\n\t * @param dataProcessingCodepath - Which code-path failed while processing data.\n\t * @param messageLike - Message to include info about via telemetry props.\n\t *\n\t * @returns Either a new `DataProcessingError`, or (if wrapping is deemed unnecessary) the given error.\n\t */\n\tpublic static wrapIfUnrecognized(\n\t\toriginalError: unknown,\n\t\tdataProcessingCodepath: string,\n\t\tmessageLike?: Partial<\n\t\t\tPick<\n\t\t\t\tISequencedDocumentMessage,\n\t\t\t\t| \"clientId\"\n\t\t\t\t| \"sequenceNumber\"\n\t\t\t\t| \"clientSequenceNumber\"\n\t\t\t\t| \"referenceSequenceNumber\"\n\t\t\t\t| \"minimumSequenceNumber\"\n\t\t\t\t| \"timestamp\"\n\t\t\t>\n\t\t>,\n\t): IFluidErrorBase {\n\t\tconst props = {\n\t\t\tdataProcessingError: 1,\n\t\t\tdataProcessingCodepath,\n\t\t\t...(messageLike === undefined\n\t\t\t\t? undefined\n\t\t\t\t: extractSafePropertiesFromMessage(messageLike)),\n\t\t};\n\n\t\tconst normalizedError = normalizeError(originalError, { props });\n\t\t// Note that other errors may have the NORMALIZED_ERROR_TYPE errorType,\n\t\t// but if so they are still suitable to be wrapped as DataProcessingError.\n\t\tif (\n\t\t\tisExternalError(normalizedError) ||\n\t\t\tnormalizedError.errorType === NORMALIZED_ERROR_TYPE\n\t\t) {\n\t\t\t// Create a new DataProcessingError to wrap this external error\n\t\t\tconst dataProcessingError = wrapError(\n\t\t\t\tnormalizedError,\n\t\t\t\t(message: string) => new DataProcessingError(message),\n\t\t\t);\n\n\t\t\t// Copy over the props above and any others added to this error since first being normalized\n\t\t\tdataProcessingError.addTelemetryProperties(normalizedError.getTelemetryProperties());\n\n\t\t\treturn dataProcessingError;\n\t\t}\n\t\treturn normalizedError;\n\t}\n}\n\n/**\n * Error indicating that two Fluid layers are incompatible.\n * See {@link @fluidframework/core-interfaces#ILayerIncompatibilityError} for more details.\n *\n * @internal\n */\nexport class LayerIncompatibilityError\n\textends LoggingError\n\timplements ILayerIncompatibilityError\n{\n\tpublic readonly errorType = FluidErrorTypesAlpha.layerIncompatibilityError;\n\tpublic readonly layer: string;\n\tpublic readonly layerVersion: string;\n\tpublic readonly incompatibleLayer: string;\n\tpublic readonly incompatibleLayerVersion: string;\n\tpublic readonly compatibilityRequirementsInMonths: number;\n\tpublic readonly actualDifferenceInMonths: number;\n\tpublic readonly details: string;\n\n\tpublic constructor(\n\t\tmessage: string,\n\t\tincompatibilityProps: {\n\t\t\tlayer: string;\n\t\t\tlayerVersion: string;\n\t\t\tincompatibleLayer: string;\n\t\t\tincompatibleLayerVersion: string;\n\t\t\tcompatibilityRequirementsInMonths: number;\n\t\t\tactualDifferenceInMonths: number;\n\t\t\tdetails: string;\n\t\t},\n\t\ttelemetryProps?: ITelemetryBaseProperties,\n\t) {\n\t\tsuper(message, {\n\t\t\t...incompatibilityProps,\n\t\t\t...telemetryProps,\n\t\t\tlayerIncompatibilityError: true,\n\t\t});\n\t\tthis.layer = incompatibilityProps.layer;\n\t\tthis.layerVersion = incompatibilityProps.layerVersion;\n\t\tthis.incompatibleLayer = incompatibilityProps.incompatibleLayer;\n\t\tthis.incompatibleLayerVersion = incompatibilityProps.incompatibleLayerVersion;\n\t\tthis.compatibilityRequirementsInMonths =\n\t\t\tincompatibilityProps.compatibilityRequirementsInMonths;\n\t\tthis.actualDifferenceInMonths = incompatibilityProps.actualDifferenceInMonths;\n\t\tthis.details = incompatibilityProps.details;\n\t}\n}\n\n/**\n * Extracts specific properties from the provided message that we know are safe to log.\n *\n * @param messageLike - Message to include info about via telemetry props.\n *\n * @internal\n */\nexport const extractSafePropertiesFromMessage = (\n\tmessageLike: Partial<\n\t\tPick<\n\t\t\tISequencedDocumentMessage,\n\t\t\t| \"clientId\"\n\t\t\t| \"sequenceNumber\"\n\t\t\t| \"clientSequenceNumber\"\n\t\t\t| \"referenceSequenceNumber\"\n\t\t\t| \"minimumSequenceNumber\"\n\t\t\t| \"timestamp\"\n\t\t>\n\t>,\n): {\n\tmessageClientId: string | undefined;\n\tmessageSequenceNumber: number | undefined;\n\tmessageClientSequenceNumber: number | undefined;\n\tmessageReferenceSequenceNumber: number | undefined;\n\tmessageMinimumSequenceNumber: number | undefined;\n\tmessageTimestamp: number | undefined;\n} => ({\n\tmessageClientId: messageLike.clientId === null ? \"null\" : messageLike.clientId,\n\tmessageSequenceNumber: messageLike.sequenceNumber,\n\tmessageClientSequenceNumber: messageLike.clientSequenceNumber,\n\tmessageReferenceSequenceNumber: messageLike.referenceSequenceNumber,\n\tmessageMinimumSequenceNumber: messageLike.minimumSequenceNumber,\n\tmessageTimestamp: messageLike.timestamp,\n});\n"]}
|
|
1
|
+
{"version":3,"file":"error.js","sourceRoot":"","sources":["../src/error.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACN,eAAe,GAIf,MAAM,0CAA0C,CAAC;AAGlD,OAAO,EACN,YAAY,EACZ,qBAAqB,EACrB,eAAe,EACf,cAAc,EACd,SAAS,GACT,MAAM,mBAAmB,CAAC;AAI3B;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CACnC,SAAkB,EAClB,OAAe,EACf,KAAgC;IAEhC,IAAI,CAAC,SAAS,EAAE,CAAC;QAChB,MAAM,IAAI,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IACtC,CAAC;AACF,CAAC;AAED;;;;GAIG;AACH,MAAM,OAAO,YAAa,SAAQ,YAAY;IAG7C;;;;;OAKG;IACH,YACC,OAAe;IACf,mIAAmI;IACnI,iHAAiH;IACjG,KAAW,EAC3B,KAAgC;QAEhC,mCAAmC;QACnC,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QAJ1B,UAAK,GAAL,KAAK,CAAM;QAZZ,cAAS,GAAG,eAAe,CAAC,YAAY,CAAC;IAiBzD,CAAC;CACD;AAED;;;;GAIG;AACH,MAAM,OAAO,UAAW,SAAQ,YAAY;IAG3C,YAAmB,OAAe,EAAE,KAAgC;QACnE,KAAK,CAAC,OAAO,EAAE,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC;QAHhC,cAAS,GAAG,eAAe,CAAC,UAAU,CAAC;IAIvD,CAAC;CACD;AAED;;;;;GAKG;AACH,MAAM,OAAO,mBAAoB,SAAQ,YAAY;IAIpD,YAAmB,OAAe,EAAE,KAA+B;QAClE,KAAK,CAAC,OAAO,EAAE,EAAE,GAAG,KAAK,EAAE,mBAAmB,EAAE,CAAC,EAAE,CAAC,CAAC;QAJtC,cAAS,GAAG,eAAe,CAAC,mBAAmB,CAAC;QAChD,aAAQ,GAAG,KAAK,CAAC;IAIjC,CAAC;CACD;AAED;;;;;;;;;;GAUG;AACH,MAAM,OAAO,mBAAoB,SAAQ,YAAY;IAQpD,YAAoB,YAAoB,EAAE,KAAgC;QACzE,KAAK,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;QAR5B;;WAEG;QACa,cAAS,GAAG,eAAe,CAAC,mBAAmB,CAAC;QAEhD,aAAQ,GAAG,KAAK,CAAC;IAIjC,CAAC;IAED;;OAEG;IACI,MAAM,CAAC,MAAM,CACnB,YAAoB,EACpB,sBAA8B,EAC9B,WAUC,EACD,QAAiC,EAAE,EACnC,eAAwB;QAExB,MAAM,WAAW,GAAG,KAA+C,CAAC;QACpE,MAAM,uBAAuB,GAAG,WAAW,CAAC,eAAe,CAAC;QAC5D,IAAI,CAAC;YACJ,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;gBACnC,WAAW,CAAC,eAAe,GAAG,eAAe,CAAC;YAC/C,CAAC;YAED,MAAM,mBAAmB,GAAG,mBAAmB,CAAC,kBAAkB,CACjE,YAAY,EACZ,sBAAsB,EACtB,WAAW,CACX,CAAC;YACF,mBAAmB,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;YAElD,OAAO,mBAAmB,CAAC;QAC5B,CAAC;gBAAS,CAAC;YACV,oDAAoD;YACpD,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;gBACnC,WAAW,CAAC,eAAe,GAAG,uBAAuB,CAAC;YACvD,CAAC;QACF,CAAC;IACF,CAAC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACI,MAAM,CAAC,kBAAkB,CAC/B,aAAsB,EACtB,sBAA8B,EAC9B,WAUC;QAED,MAAM,KAAK,GAAG;YACb,mBAAmB,EAAE,CAAC;YACtB,sBAAsB;YACtB,GAAG,CAAC,WAAW,KAAK,SAAS;gBAC5B,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,gCAAgC,CAAC,WAAW,CAAC,CAAC;SACjD,CAAC;QAEF,MAAM,eAAe,GAAG,cAAc,CAAC,aAAa,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QACjE,uEAAuE;QACvE,0EAA0E;QAC1E,IACC,eAAe,CAAC,eAAe,CAAC;YAChC,eAAe,CAAC,SAAS,KAAK,qBAAqB,EAClD,CAAC;YACF,+DAA+D;YAC/D,MAAM,mBAAmB,GAAG,SAAS,CACpC,eAAe,EACf,CAAC,OAAe,EAAE,EAAE,CAAC,IAAI,mBAAmB,CAAC,OAAO,CAAC,CACrD,CAAC;YAEF,4FAA4F;YAC5F,mBAAmB,CAAC,sBAAsB,CAAC,eAAe,CAAC,sBAAsB,EAAE,CAAC,CAAC;YAErF,OAAO,mBAAmB,CAAC;QAC5B,CAAC;QACD,OAAO,eAAe,CAAC;IACxB,CAAC;CACD;AAED;;;;;GAKG;AACH,MAAM,OAAO,yBACZ,SAAQ,YAAY;IAYpB,YACC,OAAe,EACf,oBAQC,EACD,cAAyC;QAEzC,KAAK,CAAC,OAAO,EAAE;YACd,GAAG,oBAAoB;YACvB,GAAG,cAAc;YACjB,yBAAyB,EAAE,IAAI;SAC/B,CAAC,CAAC;QA1BY,cAAS,GAAG,eAAe,CAAC,yBAAyB,CAAC;QA2BrE,IAAI,CAAC,KAAK,GAAG,oBAAoB,CAAC,KAAK,CAAC;QACxC,IAAI,CAAC,YAAY,GAAG,oBAAoB,CAAC,YAAY,CAAC;QACtD,IAAI,CAAC,iBAAiB,GAAG,oBAAoB,CAAC,iBAAiB,CAAC;QAChE,IAAI,CAAC,wBAAwB,GAAG,oBAAoB,CAAC,wBAAwB,CAAC;QAC9E,IAAI,CAAC,iCAAiC;YACrC,oBAAoB,CAAC,iCAAiC,CAAC;QACxD,IAAI,CAAC,wBAAwB,GAAG,oBAAoB,CAAC,wBAAwB,CAAC;QAC9E,IAAI,CAAC,OAAO,GAAG,oBAAoB,CAAC,OAAO,CAAC;IAC7C,CAAC;CACD;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,gCAAgC,GAAG,CAC/C,WAUC,EAQA,EAAE,CAAC,CAAC;IACL,eAAe,EAAE,WAAW,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ;IAC9E,qBAAqB,EAAE,WAAW,CAAC,cAAc;IACjD,2BAA2B,EAAE,WAAW,CAAC,oBAAoB;IAC7D,8BAA8B,EAAE,WAAW,CAAC,uBAAuB;IACnE,4BAA4B,EAAE,WAAW,CAAC,qBAAqB;IAC/D,gBAAgB,EAAE,WAAW,CAAC,SAAS;CACvC,CAAC,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { IErrorBase, ITelemetryBaseProperties } from \"@fluidframework/core-interfaces\";\nimport {\n\tFluidErrorTypes,\n\ttype IGenericError,\n\ttype ILayerIncompatibilityError,\n\ttype IUsageError,\n} from \"@fluidframework/core-interfaces/internal\";\nimport type { ISequencedDocumentMessage } from \"@fluidframework/driver-definitions/internal\";\n\nimport {\n\tLoggingError,\n\tNORMALIZED_ERROR_TYPE,\n\tisExternalError,\n\tnormalizeError,\n\twrapError,\n} from \"./errorLogging.js\";\nimport type { IFluidErrorBase } from \"./fluidErrorBase.js\";\nimport type { ITelemetryPropertiesExt } from \"./telemetryTypes.js\";\n\n/**\n * Throws a UsageError with the given message if the condition is not met.\n * Use this API when `false` indicates a precondition is not met on a public API (for any FF layer).\n *\n * @param condition - The condition that should be true, if the condition is false a UsageError will be thrown.\n * @param message - The message to include in the error when the condition does not hold.\n * @param props - Telemetry props to include on the error when the condition does not hold.\n * @internal\n */\nexport function validatePrecondition(\n\tcondition: boolean,\n\tmessage: string,\n\tprops?: ITelemetryBaseProperties,\n): asserts condition {\n\tif (!condition) {\n\t\tthrow new UsageError(message, props);\n\t}\n}\n\n/**\n * Generic wrapper for an unrecognized/uncategorized error object\n *\n * @internal\n */\nexport class GenericError extends LoggingError implements IGenericError, IFluidErrorBase {\n\tpublic readonly errorType = FluidErrorTypes.genericError;\n\n\t/**\n\t * Create a new GenericError\n\t * @param message - Error message\n\t * @param error - inner error object\n\t * @param props - Telemetry props to include when the error is logged\n\t */\n\tpublic constructor(\n\t\tmessage: string,\n\t\t// TODO: Use `unknown` instead (API breaking change because error is not just an input parameter, but a public member of the class)\n\t\t// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any\n\t\tpublic readonly error?: any,\n\t\tprops?: ITelemetryBaseProperties,\n\t) {\n\t\t// Don't try to log the inner error\n\t\tsuper(message, props, new Set([\"error\"]));\n\t}\n}\n\n/**\n * Error indicating an API is being used improperly resulting in an invalid operation.\n *\n * @internal\n */\nexport class UsageError extends LoggingError implements IUsageError, IFluidErrorBase {\n\tpublic readonly errorType = FluidErrorTypes.usageError;\n\n\tpublic constructor(message: string, props?: ITelemetryBaseProperties) {\n\t\tsuper(message, { ...props, usageError: true });\n\t}\n}\n\n/**\n * DataCorruptionError indicates that we encountered definitive evidence that the data at rest\n * backing this container is corrupted, and this container would never be expected to load properly again\n *\n * @internal\n */\nexport class DataCorruptionError extends LoggingError implements IErrorBase, IFluidErrorBase {\n\tpublic readonly errorType = FluidErrorTypes.dataCorruptionError;\n\tpublic readonly canRetry = false;\n\n\tpublic constructor(message: string, props: ITelemetryBaseProperties) {\n\t\tsuper(message, { ...props, dataProcessingError: 1 });\n\t}\n}\n\n/**\n * Indicates we hit a fatal error while processing incoming data from the Fluid Service.\n *\n * @remarks\n *\n * The error will often originate in the dataStore or DDS implementation that is responding to incoming changes.\n * This differs from {@link DataCorruptionError} in that this may be a transient error that will not repro in another\n * client or session.\n *\n * @internal\n */\nexport class DataProcessingError extends LoggingError implements IErrorBase, IFluidErrorBase {\n\t/**\n\t * {@inheritDoc IFluidErrorBase.errorType}\n\t */\n\tpublic readonly errorType = FluidErrorTypes.dataProcessingError;\n\n\tpublic readonly canRetry = false;\n\n\tprivate constructor(errorMessage: string, props?: ITelemetryBaseProperties) {\n\t\tsuper(errorMessage, props);\n\t}\n\n\t/**\n\t * Create a new `DataProcessingError` detected and raised within the Fluid Framework.\n\t */\n\tpublic static create(\n\t\terrorMessage: string,\n\t\tdataProcessingCodepath: string,\n\t\tmessageLike?: Partial<\n\t\t\tPick<\n\t\t\t\tISequencedDocumentMessage,\n\t\t\t\t| \"clientId\"\n\t\t\t\t| \"sequenceNumber\"\n\t\t\t\t| \"clientSequenceNumber\"\n\t\t\t\t| \"referenceSequenceNumber\"\n\t\t\t\t| \"minimumSequenceNumber\"\n\t\t\t\t| \"timestamp\"\n\t\t\t>\n\t\t>,\n\t\tprops: ITelemetryPropertiesExt = {},\n\t\tstackTraceLimit?: number,\n\t): IFluidErrorBase {\n\t\tconst ErrorConfig = Error as unknown as { stackTraceLimit: number };\n\t\tconst originalStackTraceLimit = ErrorConfig.stackTraceLimit;\n\t\ttry {\n\t\t\tif (stackTraceLimit !== undefined) {\n\t\t\t\tErrorConfig.stackTraceLimit = stackTraceLimit;\n\t\t\t}\n\n\t\t\tconst dataProcessingError = DataProcessingError.wrapIfUnrecognized(\n\t\t\t\terrorMessage,\n\t\t\t\tdataProcessingCodepath,\n\t\t\t\tmessageLike,\n\t\t\t);\n\t\t\tdataProcessingError.addTelemetryProperties(props);\n\n\t\t\treturn dataProcessingError;\n\t\t} finally {\n\t\t\t// Reset the stack trace limit to the original value\n\t\t\tif (stackTraceLimit !== undefined) {\n\t\t\t\tErrorConfig.stackTraceLimit = originalStackTraceLimit;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Wrap the given error in a `DataProcessingError`, unless the error is already of a known type\n\t * with the exception of a normalized {@link LoggingError}, which will still be wrapped.\n\t *\n\t * In either case, the error will have some relevant properties added for telemetry.\n\t *\n\t * @remarks\n\t *\n\t * We wrap conditionally since known error types represent well-understood failure modes, and ideally\n\t * one day we will move away from throwing these errors but rather we'll return them.\n\t * But an unrecognized error needs to be classified as `DataProcessingError`.\n\t *\n\t * @param originalError - The error to be converted.\n\t * @param dataProcessingCodepath - Which code-path failed while processing data.\n\t * @param messageLike - Message to include info about via telemetry props.\n\t *\n\t * @returns Either a new `DataProcessingError`, or (if wrapping is deemed unnecessary) the given error.\n\t */\n\tpublic static wrapIfUnrecognized(\n\t\toriginalError: unknown,\n\t\tdataProcessingCodepath: string,\n\t\tmessageLike?: Partial<\n\t\t\tPick<\n\t\t\t\tISequencedDocumentMessage,\n\t\t\t\t| \"clientId\"\n\t\t\t\t| \"sequenceNumber\"\n\t\t\t\t| \"clientSequenceNumber\"\n\t\t\t\t| \"referenceSequenceNumber\"\n\t\t\t\t| \"minimumSequenceNumber\"\n\t\t\t\t| \"timestamp\"\n\t\t\t>\n\t\t>,\n\t): IFluidErrorBase {\n\t\tconst props = {\n\t\t\tdataProcessingError: 1,\n\t\t\tdataProcessingCodepath,\n\t\t\t...(messageLike === undefined\n\t\t\t\t? undefined\n\t\t\t\t: extractSafePropertiesFromMessage(messageLike)),\n\t\t};\n\n\t\tconst normalizedError = normalizeError(originalError, { props });\n\t\t// Note that other errors may have the NORMALIZED_ERROR_TYPE errorType,\n\t\t// but if so they are still suitable to be wrapped as DataProcessingError.\n\t\tif (\n\t\t\tisExternalError(normalizedError) ||\n\t\t\tnormalizedError.errorType === NORMALIZED_ERROR_TYPE\n\t\t) {\n\t\t\t// Create a new DataProcessingError to wrap this external error\n\t\t\tconst dataProcessingError = wrapError(\n\t\t\t\tnormalizedError,\n\t\t\t\t(message: string) => new DataProcessingError(message),\n\t\t\t);\n\n\t\t\t// Copy over the props above and any others added to this error since first being normalized\n\t\t\tdataProcessingError.addTelemetryProperties(normalizedError.getTelemetryProperties());\n\n\t\t\treturn dataProcessingError;\n\t\t}\n\t\treturn normalizedError;\n\t}\n}\n\n/**\n * Error indicating that two Fluid layers are incompatible.\n * See {@link @fluidframework/core-interfaces#ILayerIncompatibilityError} for more details.\n *\n * @internal\n */\nexport class LayerIncompatibilityError\n\textends LoggingError\n\timplements ILayerIncompatibilityError\n{\n\tpublic readonly errorType = FluidErrorTypes.layerIncompatibilityError;\n\tpublic readonly layer: string;\n\tpublic readonly layerVersion: string;\n\tpublic readonly incompatibleLayer: string;\n\tpublic readonly incompatibleLayerVersion: string;\n\tpublic readonly compatibilityRequirementsInMonths: number;\n\tpublic readonly actualDifferenceInMonths: number;\n\tpublic readonly details: string;\n\n\tpublic constructor(\n\t\tmessage: string,\n\t\tincompatibilityProps: {\n\t\t\tlayer: string;\n\t\t\tlayerVersion: string;\n\t\t\tincompatibleLayer: string;\n\t\t\tincompatibleLayerVersion: string;\n\t\t\tcompatibilityRequirementsInMonths: number;\n\t\t\tactualDifferenceInMonths: number;\n\t\t\tdetails: string;\n\t\t},\n\t\ttelemetryProps?: ITelemetryBaseProperties,\n\t) {\n\t\tsuper(message, {\n\t\t\t...incompatibilityProps,\n\t\t\t...telemetryProps,\n\t\t\tlayerIncompatibilityError: true,\n\t\t});\n\t\tthis.layer = incompatibilityProps.layer;\n\t\tthis.layerVersion = incompatibilityProps.layerVersion;\n\t\tthis.incompatibleLayer = incompatibilityProps.incompatibleLayer;\n\t\tthis.incompatibleLayerVersion = incompatibilityProps.incompatibleLayerVersion;\n\t\tthis.compatibilityRequirementsInMonths =\n\t\t\tincompatibilityProps.compatibilityRequirementsInMonths;\n\t\tthis.actualDifferenceInMonths = incompatibilityProps.actualDifferenceInMonths;\n\t\tthis.details = incompatibilityProps.details;\n\t}\n}\n\n/**\n * Extracts specific properties from the provided message that we know are safe to log.\n *\n * @param messageLike - Message to include info about via telemetry props.\n *\n * @internal\n */\nexport const extractSafePropertiesFromMessage = (\n\tmessageLike: Partial<\n\t\tPick<\n\t\t\tISequencedDocumentMessage,\n\t\t\t| \"clientId\"\n\t\t\t| \"sequenceNumber\"\n\t\t\t| \"clientSequenceNumber\"\n\t\t\t| \"referenceSequenceNumber\"\n\t\t\t| \"minimumSequenceNumber\"\n\t\t\t| \"timestamp\"\n\t\t>\n\t>,\n): {\n\tmessageClientId: string | undefined;\n\tmessageSequenceNumber: number | undefined;\n\tmessageClientSequenceNumber: number | undefined;\n\tmessageReferenceSequenceNumber: number | undefined;\n\tmessageMinimumSequenceNumber: number | undefined;\n\tmessageTimestamp: number | undefined;\n} => ({\n\tmessageClientId: messageLike.clientId === null ? \"null\" : messageLike.clientId,\n\tmessageSequenceNumber: messageLike.sequenceNumber,\n\tmessageClientSequenceNumber: messageLike.clientSequenceNumber,\n\tmessageReferenceSequenceNumber: messageLike.referenceSequenceNumber,\n\tmessageMinimumSequenceNumber: messageLike.minimumSequenceNumber,\n\tmessageTimestamp: messageLike.timestamp,\n});\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fluidErrorBase.d.ts","sourceRoot":"","sources":["../src/fluidErrorBase.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAChF,OAAO,EAEN,KAAK,0BAA0B,EAC/B,MAAM,0CAA0C,CAAC;AAElD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAEnE;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,eAAgB,SAAQ,KAAK;IAC7C;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B;;;;;;;;;OASG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;;;;;;OAOG;IACH,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IAEjC;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;OAEG;IACH,sBAAsB,IAAI,wBAAwB,CAAC;IAEnD;;OAEG;IACH,sBAAsB,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,IAAI,CAAC;CACjE;AAMD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,MAAO,OAAO;qBAA2B,MAAM;CACG,CAAC;AAElF;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,eAAe,CAOrE;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAC1C,KAAK,EAAE,OAAO,GACZ,KAAK,IAAI,0BAA0B,
|
|
1
|
+
{"version":3,"file":"fluidErrorBase.d.ts","sourceRoot":"","sources":["../src/fluidErrorBase.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAChF,OAAO,EAEN,KAAK,0BAA0B,EAC/B,MAAM,0CAA0C,CAAC;AAElD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAEnE;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,eAAgB,SAAQ,KAAK;IAC7C;;;;OAIG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B;;;;;;;;;OASG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAEzB;;OAEG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAExB;;OAEG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;;;;;;OAOG;IACH,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IAEjC;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;OAEG;IACH,sBAAsB,IAAI,wBAAwB,CAAC;IAEnD;;OAEG;IACH,sBAAsB,EAAE,CAAC,KAAK,EAAE,uBAAuB,KAAK,IAAI,CAAC;CACjE;AAMD;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,MAAO,OAAO;qBAA2B,MAAM;CACG,CAAC;AAElF;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,eAAe,CAOrE;AAED;;;;GAIG;AACH,wBAAgB,2BAA2B,CAC1C,KAAK,EAAE,OAAO,GACZ,KAAK,IAAI,0BAA0B,CAErC"}
|
package/lib/fluidErrorBase.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
import {
|
|
5
|
+
import { FluidErrorTypes, } from "@fluidframework/core-interfaces/internal";
|
|
6
6
|
const hasTelemetryPropFunctions = (x) => typeof x?.getTelemetryProperties === "function" &&
|
|
7
7
|
typeof x?.addTelemetryProperties === "function";
|
|
8
8
|
/**
|
|
@@ -28,6 +28,6 @@ export function isFluidError(error) {
|
|
|
28
28
|
* @internal
|
|
29
29
|
*/
|
|
30
30
|
export function isLayerIncompatibilityError(error) {
|
|
31
|
-
return
|
|
31
|
+
return isFluidError(error) && error.errorType === FluidErrorTypes.layerIncompatibilityError;
|
|
32
32
|
}
|
|
33
33
|
//# sourceMappingURL=fluidErrorBase.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fluidErrorBase.js","sourceRoot":"","sources":["../src/fluidErrorBase.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACN,
|
|
1
|
+
{"version":3,"file":"fluidErrorBase.js","sourceRoot":"","sources":["../src/fluidErrorBase.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACN,eAAe,GAEf,MAAM,0CAA0C,CAAC;AAkFlD,MAAM,yBAAyB,GAAG,CAAC,CAAU,EAAW,EAAE,CACzD,OAAQ,CAA8B,EAAE,sBAAsB,KAAK,UAAU;IAC7E,OAAQ,CAA8B,EAAE,sBAAsB,KAAK,UAAU,CAAC;AAE/E;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAU,EAAoC,EAAE,CAClF,OAAQ,CAA0C,EAAE,eAAe,KAAK,QAAQ,CAAC;AAElF;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,KAAc;IAC1C,OAAO,CACN,OAAQ,KAAkC,EAAE,SAAS,KAAK,QAAQ;QAClE,OAAQ,KAAkC,EAAE,OAAO,KAAK,QAAQ;QAChE,kBAAkB,CAAC,KAAK,CAAC;QACzB,yBAAyB,CAAC,KAAK,CAAC,CAChC,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CAC1C,KAAc;IAEd,OAAO,YAAY,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,SAAS,KAAK,eAAe,CAAC,yBAAyB,CAAC;AAC7F,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport type { ITelemetryBaseProperties } from \"@fluidframework/core-interfaces\";\nimport {\n\tFluidErrorTypes,\n\ttype ILayerIncompatibilityError,\n} from \"@fluidframework/core-interfaces/internal\";\n\nimport type { ITelemetryPropertiesExt } from \"./telemetryTypes.js\";\n\n/**\n * An error emitted by the Fluid Framework.\n *\n * @remarks\n *\n * All normalized errors flowing through the Fluid Framework adhere to this readonly interface.\n *\n * It features the members of {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error | Error}\n * made readonly, as well as {@link IFluidErrorBase.errorType} and {@link IFluidErrorBase.errorInstanceId}.\n * It also features getters and setters for telemetry props to be included when the error is logged.\n *\n * @internal\n */\nexport interface IFluidErrorBase extends Error {\n\t/**\n\t * Classification of what type of error this is.\n\t *\n\t * @remarks Used programmatically by consumers to interpret the error.\n\t */\n\treadonly errorType: string;\n\n\t/**\n\t * Error's message property, made readonly.\n\t *\n\t * @remarks\n\t *\n\t * Recommendations:\n\t *\n\t * Be specific, but also take care when including variable data to consider suitability for aggregation in telemetry.\n\t * Also avoid including any data that jeopardizes the user's privacy. Add a tagged telemetry property instead.\n\t */\n\treadonly message: string;\n\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/stack}.\n\t */\n\treadonly stack?: string;\n\n\t/**\n\t * See {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/name}.\n\t */\n\treadonly name: string;\n\n\t/**\n\t * A Guid identifying this error instance.\n\t *\n\t * @remarks\n\t *\n\t * Useful in telemetry for deduplicating multiple logging events arising from the same error,\n\t * or correlating an error with an inner error that caused it, in case of error wrapping.\n\t */\n\treadonly errorInstanceId: string;\n\n\t/**\n\t * When present, inner error that caused this error.\n\t *\n\t * @remarks\n\t * This will often be an {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error|Error}, but could be any type.\n\t *\n\t * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause\n\t *\n\t * @privateRemarks\n\t * The \"cause\" field is added in ES2022. Using it even without that built-in support, is still helpful.\n\t * TODO: remove this declaration (use `Error.cause` property) when targeting ES2022 lib or later.\n\t */\n\tcause?: unknown;\n\n\t/**\n\t * Get the telemetry properties stashed on this error for logging.\n\t */\n\tgetTelemetryProperties(): ITelemetryBaseProperties;\n\n\t/**\n\t * Add telemetry properties to this error which will be logged with the error\n\t */\n\taddTelemetryProperties: (props: ITelemetryPropertiesExt) => void;\n}\n\nconst hasTelemetryPropFunctions = (x: unknown): boolean =>\n\ttypeof (x as Partial<IFluidErrorBase>)?.getTelemetryProperties === \"function\" &&\n\ttypeof (x as Partial<IFluidErrorBase>)?.addTelemetryProperties === \"function\";\n\n/**\n * Type guard for error data containing the {@link IFluidErrorBase.errorInstanceId} property.\n *\n * @internal\n */\nexport const hasErrorInstanceId = (x: unknown): x is { errorInstanceId: string } =>\n\ttypeof (x as Partial<{ errorInstanceId: string }>)?.errorInstanceId === \"string\";\n\n/**\n * Type guard for {@link IFluidErrorBase}.\n *\n * @internal\n */\nexport function isFluidError(error: unknown): error is IFluidErrorBase {\n\treturn (\n\t\ttypeof (error as Partial<IFluidErrorBase>)?.errorType === \"string\" &&\n\t\ttypeof (error as Partial<IFluidErrorBase>)?.message === \"string\" &&\n\t\thasErrorInstanceId(error) &&\n\t\thasTelemetryPropFunctions(error)\n\t);\n}\n\n/**\n * Helper that returns whether the provided error is a layer incompatibility error.\n *\n * @internal\n */\nexport function isLayerIncompatibilityError(\n\terror: unknown,\n): error is ILayerIncompatibilityError {\n\treturn isFluidError(error) && error.errorType === FluidErrorTypes.layerIncompatibilityError;\n}\n"]}
|
package/lib/index.d.ts
CHANGED
|
@@ -15,5 +15,5 @@ export { SampledTelemetryHelper, type CustomMetrics, type ICustomData, type Meas
|
|
|
15
15
|
export { createSampledLogger, type IEventSampler, type ISampledTelemetryLogger, measure, } from "./utils.js";
|
|
16
16
|
export type { TelemetryEventPropertyTypeExt, ITelemetryEventExt, ITelemetryGenericEventExt, ITelemetryErrorEventExt, ITelemetryPerformanceEventExt, ITelemetryLoggerExt, ITelemetryPropertiesExt, TelemetryEventCategory, } from "./telemetryTypes.js";
|
|
17
17
|
export { TelemetryEventBatcher } from "./telemetryEventBatcher.js";
|
|
18
|
-
export { validateLayerCompatibility } from "./layerCompatError.js";
|
|
18
|
+
export { allowIncompatibleLayersKey, validateLayerCompatibility } from "./layerCompatError.js";
|
|
19
19
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,4BAA4B,EAC5B,KAAK,iBAAiB,EACtB,4BAA4B,EAC5B,sBAAsB,EACtB,KAAK,eAAe,EACpB,yBAAyB,EACzB,8BAA8B,EAC9B,6BAA6B,EAC7B,KAAK,mBAAmB,GACxB,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,mBAAmB,EACnB,mBAAmB,EACnB,gCAAgC,EAChC,YAAY,EACZ,UAAU,EACV,oBAAoB,EACpB,yBAAyB,GACzB,MAAM,YAAY,CAAC;AACpB,OAAO,EACN,6BAA6B,EAC7B,sBAAsB,EACtB,aAAa,EACb,mBAAmB,EACnB,KAAK,sBAAsB,EAC3B,eAAe,EACf,eAAe,EACf,8BAA8B,EAC9B,YAAY,EACZ,qBAAqB,EACrB,cAAc,EACd,cAAc,EACd,SAAS,EACT,eAAe,GACf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,6BAA6B,EAAE,MAAM,oCAAoC,CAAC;AACnF,OAAO,EACN,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,GACd,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,kBAAkB,EAClB,KAAK,eAAe,EACpB,YAAY,EACZ,2BAA2B,GAC3B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,UAAU,EACV,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,EACjC,KAAK,yBAAyB,EAC9B,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,OAAO,EACP,gBAAgB,EAChB,gBAAgB,EAChB,KAAK,2BAA2B,GAChC,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,mBAAmB,EACnB,KAAK,cAAc,EACnB,UAAU,GACV,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EACN,sBAAsB,EACtB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,iBAAiB,GACtB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACN,mBAAmB,EACnB,KAAK,aAAa,EAClB,KAAK,uBAAuB,EAC5B,OAAO,GACP,MAAM,YAAY,CAAC;AACpB,YAAY,EACX,6BAA6B,EAC7B,kBAAkB,EAClB,yBAAyB,EACzB,uBAAuB,EACvB,6BAA6B,EAC7B,mBAAmB,EACnB,uBAAuB,EACvB,sBAAsB,GACtB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,4BAA4B,EAC5B,KAAK,iBAAiB,EACtB,4BAA4B,EAC5B,sBAAsB,EACtB,KAAK,eAAe,EACpB,yBAAyB,EACzB,8BAA8B,EAC9B,6BAA6B,EAC7B,KAAK,mBAAmB,GACxB,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,mBAAmB,EACnB,mBAAmB,EACnB,gCAAgC,EAChC,YAAY,EACZ,UAAU,EACV,oBAAoB,EACpB,yBAAyB,GACzB,MAAM,YAAY,CAAC;AACpB,OAAO,EACN,6BAA6B,EAC7B,sBAAsB,EACtB,aAAa,EACb,mBAAmB,EACnB,KAAK,sBAAsB,EAC3B,eAAe,EACf,eAAe,EACf,8BAA8B,EAC9B,YAAY,EACZ,qBAAqB,EACrB,cAAc,EACd,cAAc,EACd,SAAS,EACT,eAAe,GACf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,6BAA6B,EAAE,MAAM,oCAAoC,CAAC;AACnF,OAAO,EACN,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,GACd,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,kBAAkB,EAClB,KAAK,eAAe,EACpB,YAAY,EACZ,2BAA2B,GAC3B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,UAAU,EACV,KAAK,wBAAwB,EAC7B,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,EACjC,KAAK,yBAAyB,EAC9B,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,OAAO,EACP,gBAAgB,EAChB,gBAAgB,EAChB,KAAK,2BAA2B,GAChC,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,mBAAmB,EACnB,KAAK,cAAc,EACnB,UAAU,GACV,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EACN,sBAAsB,EACtB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,iBAAiB,GACtB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACN,mBAAmB,EACnB,KAAK,aAAa,EAClB,KAAK,uBAAuB,EAC5B,OAAO,GACP,MAAM,YAAY,CAAC;AACpB,YAAY,EACX,6BAA6B,EAC7B,kBAAkB,EAClB,yBAAyB,EACzB,uBAAuB,EACvB,6BAA6B,EAC7B,mBAAmB,EACnB,uBAAuB,EACvB,sBAAsB,GACtB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,0BAA0B,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC"}
|
package/lib/index.js
CHANGED
|
@@ -14,5 +14,5 @@ export { ThresholdCounter } from "./thresholdCounter.js";
|
|
|
14
14
|
export { SampledTelemetryHelper, } from "./sampledTelemetryHelper.js";
|
|
15
15
|
export { createSampledLogger, measure, } from "./utils.js";
|
|
16
16
|
export { TelemetryEventBatcher } from "./telemetryEventBatcher.js";
|
|
17
|
-
export { validateLayerCompatibility } from "./layerCompatError.js";
|
|
17
|
+
export { allowIncompatibleLayersKey, validateLayerCompatibility } from "./layerCompatError.js";
|
|
18
18
|
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,4BAA4B,EAE5B,4BAA4B,EAC5B,sBAAsB,EAEtB,yBAAyB,EACzB,8BAA8B,EAC9B,6BAA6B,GAE7B,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,mBAAmB,EACnB,mBAAmB,EACnB,gCAAgC,EAChC,YAAY,EACZ,UAAU,EACV,oBAAoB,EACpB,yBAAyB,GACzB,MAAM,YAAY,CAAC;AACpB,OAAO,EACN,6BAA6B,EAC7B,sBAAsB,EACtB,aAAa,EACb,mBAAmB,EAEnB,eAAe,EACf,eAAe,EACf,8BAA8B,EAC9B,YAAY,EACZ,qBAAqB,EACrB,cAAc,EACd,cAAc,EACd,SAAS,EACT,eAAe,GACf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,6BAA6B,EAAE,MAAM,oCAAoC,CAAC;AACnF,OAAO,EACN,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,GACd,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,kBAAkB,EAElB,YAAY,EACZ,2BAA2B,GAC3B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,UAAU,EAKV,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,OAAO,EACP,gBAAgB,EAChB,gBAAgB,GAEhB,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,mBAAmB,EAEnB,UAAU,GACV,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EACN,sBAAsB,GAItB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACN,mBAAmB,EAGnB,OAAO,GACP,MAAM,YAAY,CAAC;AAWpB,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport {\n\tcreateChildMonitoringContext,\n\ttype MonitoringContext,\n\tsessionStorageConfigProvider,\n\tmixinMonitoringContext,\n\ttype IConfigProvider,\n\tloggerToMonitoringContext,\n\twrapConfigProviderWithDefaults,\n\tcreateConfigBasedOptionsProxy,\n\ttype OptionConfigReaders,\n} from \"./config.js\";\nexport {\n\tDataCorruptionError,\n\tDataProcessingError,\n\textractSafePropertiesFromMessage,\n\tGenericError,\n\tUsageError,\n\tvalidatePrecondition,\n\tLayerIncompatibilityError,\n} from \"./error.js\";\nexport {\n\textractLogSafeErrorProperties,\n\tgenerateErrorWithStack,\n\tgenerateStack,\n\tgetCircularReplacer,\n\ttype IFluidErrorAnnotations,\n\tisExternalError,\n\tisILoggingError,\n\tisTaggedTelemetryPropertyValue,\n\tLoggingError,\n\tNORMALIZED_ERROR_TYPE,\n\tnormalizeError,\n\toverwriteStack,\n\twrapError,\n\twrapErrorAndLog,\n} from \"./errorLogging.js\";\nexport { EventEmitterWithErrorHandling } from \"./eventEmitterWithErrorHandling.js\";\nexport {\n\tconnectedEventName,\n\tdisconnectedEventName,\n\traiseConnectedEvent,\n\tsafeRaiseEvent,\n} from \"./events.js\";\nexport {\n\thasErrorInstanceId,\n\ttype IFluidErrorBase,\n\tisFluidError,\n\tisLayerIncompatibilityError,\n} from \"./fluidErrorBase.js\";\nexport {\n\teventNamespaceSeparator,\n\tcreateChildLogger,\n\tcreateMultiSinkLogger,\n\tformatTick,\n\ttype IPerformanceEventMarkers,\n\ttype ITelemetryLoggerPropertyBag,\n\ttype ITelemetryLoggerPropertyBags,\n\ttype MultiSinkLoggerProperties,\n\tnumberFromString,\n\tPerformanceEvent,\n\tTaggedLoggerAdapter,\n\ttagData,\n\ttagCodeArtifacts,\n\tTelemetryDataTag,\n\ttype TelemetryEventPropertyTypes,\n} from \"./logger.js\";\nexport {\n\tcreateMockLoggerExt,\n\ttype IMockLoggerExt,\n\tMockLogger,\n} from \"./mockLogger.js\";\nexport { ThresholdCounter } from \"./thresholdCounter.js\";\nexport {\n\tSampledTelemetryHelper,\n\ttype CustomMetrics,\n\ttype ICustomData,\n\ttype MeasureReturnType,\n} from \"./sampledTelemetryHelper.js\";\nexport {\n\tcreateSampledLogger,\n\ttype IEventSampler,\n\ttype ISampledTelemetryLogger,\n\tmeasure,\n} from \"./utils.js\";\nexport type {\n\tTelemetryEventPropertyTypeExt,\n\tITelemetryEventExt,\n\tITelemetryGenericEventExt,\n\tITelemetryErrorEventExt,\n\tITelemetryPerformanceEventExt,\n\tITelemetryLoggerExt,\n\tITelemetryPropertiesExt,\n\tTelemetryEventCategory,\n} from \"./telemetryTypes.js\";\nexport { TelemetryEventBatcher } from \"./telemetryEventBatcher.js\";\nexport { validateLayerCompatibility } from \"./layerCompatError.js\";\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,4BAA4B,EAE5B,4BAA4B,EAC5B,sBAAsB,EAEtB,yBAAyB,EACzB,8BAA8B,EAC9B,6BAA6B,GAE7B,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,mBAAmB,EACnB,mBAAmB,EACnB,gCAAgC,EAChC,YAAY,EACZ,UAAU,EACV,oBAAoB,EACpB,yBAAyB,GACzB,MAAM,YAAY,CAAC;AACpB,OAAO,EACN,6BAA6B,EAC7B,sBAAsB,EACtB,aAAa,EACb,mBAAmB,EAEnB,eAAe,EACf,eAAe,EACf,8BAA8B,EAC9B,YAAY,EACZ,qBAAqB,EACrB,cAAc,EACd,cAAc,EACd,SAAS,EACT,eAAe,GACf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,6BAA6B,EAAE,MAAM,oCAAoC,CAAC;AACnF,OAAO,EACN,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,GACd,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,kBAAkB,EAElB,YAAY,EACZ,2BAA2B,GAC3B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACN,uBAAuB,EACvB,iBAAiB,EACjB,qBAAqB,EACrB,UAAU,EAKV,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,EACnB,OAAO,EACP,gBAAgB,EAChB,gBAAgB,GAEhB,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,mBAAmB,EAEnB,UAAU,GACV,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EACN,sBAAsB,GAItB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACN,mBAAmB,EAGnB,OAAO,GACP,MAAM,YAAY,CAAC;AAWpB,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,0BAA0B,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nexport {\n\tcreateChildMonitoringContext,\n\ttype MonitoringContext,\n\tsessionStorageConfigProvider,\n\tmixinMonitoringContext,\n\ttype IConfigProvider,\n\tloggerToMonitoringContext,\n\twrapConfigProviderWithDefaults,\n\tcreateConfigBasedOptionsProxy,\n\ttype OptionConfigReaders,\n} from \"./config.js\";\nexport {\n\tDataCorruptionError,\n\tDataProcessingError,\n\textractSafePropertiesFromMessage,\n\tGenericError,\n\tUsageError,\n\tvalidatePrecondition,\n\tLayerIncompatibilityError,\n} from \"./error.js\";\nexport {\n\textractLogSafeErrorProperties,\n\tgenerateErrorWithStack,\n\tgenerateStack,\n\tgetCircularReplacer,\n\ttype IFluidErrorAnnotations,\n\tisExternalError,\n\tisILoggingError,\n\tisTaggedTelemetryPropertyValue,\n\tLoggingError,\n\tNORMALIZED_ERROR_TYPE,\n\tnormalizeError,\n\toverwriteStack,\n\twrapError,\n\twrapErrorAndLog,\n} from \"./errorLogging.js\";\nexport { EventEmitterWithErrorHandling } from \"./eventEmitterWithErrorHandling.js\";\nexport {\n\tconnectedEventName,\n\tdisconnectedEventName,\n\traiseConnectedEvent,\n\tsafeRaiseEvent,\n} from \"./events.js\";\nexport {\n\thasErrorInstanceId,\n\ttype IFluidErrorBase,\n\tisFluidError,\n\tisLayerIncompatibilityError,\n} from \"./fluidErrorBase.js\";\nexport {\n\teventNamespaceSeparator,\n\tcreateChildLogger,\n\tcreateMultiSinkLogger,\n\tformatTick,\n\ttype IPerformanceEventMarkers,\n\ttype ITelemetryLoggerPropertyBag,\n\ttype ITelemetryLoggerPropertyBags,\n\ttype MultiSinkLoggerProperties,\n\tnumberFromString,\n\tPerformanceEvent,\n\tTaggedLoggerAdapter,\n\ttagData,\n\ttagCodeArtifacts,\n\tTelemetryDataTag,\n\ttype TelemetryEventPropertyTypes,\n} from \"./logger.js\";\nexport {\n\tcreateMockLoggerExt,\n\ttype IMockLoggerExt,\n\tMockLogger,\n} from \"./mockLogger.js\";\nexport { ThresholdCounter } from \"./thresholdCounter.js\";\nexport {\n\tSampledTelemetryHelper,\n\ttype CustomMetrics,\n\ttype ICustomData,\n\ttype MeasureReturnType,\n} from \"./sampledTelemetryHelper.js\";\nexport {\n\tcreateSampledLogger,\n\ttype IEventSampler,\n\ttype ISampledTelemetryLogger,\n\tmeasure,\n} from \"./utils.js\";\nexport type {\n\tTelemetryEventPropertyTypeExt,\n\tITelemetryEventExt,\n\tITelemetryGenericEventExt,\n\tITelemetryErrorEventExt,\n\tITelemetryPerformanceEventExt,\n\tITelemetryLoggerExt,\n\tITelemetryPropertiesExt,\n\tTelemetryEventCategory,\n} from \"./telemetryTypes.js\";\nexport { TelemetryEventBatcher } from \"./telemetryEventBatcher.js\";\nexport { allowIncompatibleLayersKey, validateLayerCompatibility } from \"./layerCompatError.js\";\n"]}
|
|
@@ -4,13 +4,31 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { type FluidLayer, type ILayerCompatDetails, type ILayerCompatSupportRequirements } from "@fluid-internal/client-utils";
|
|
6
6
|
import type { IErrorBase } from "@fluidframework/core-interfaces";
|
|
7
|
-
import type {
|
|
7
|
+
import type { MonitoringContext } from "./config.js";
|
|
8
|
+
/**
|
|
9
|
+
* The config key to disable layer compatibility validation.
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
export declare const allowIncompatibleLayersKey = "Fluid.AllowIncompatibleLayers";
|
|
8
13
|
/**
|
|
9
14
|
* Validates the compatibility between two layers using their compatibility details and support requirements.
|
|
10
|
-
* If the layers are incompatible, it logs
|
|
15
|
+
* If the layers are incompatible, it logs a "LayerIncompatibilityError" error event. It will also call the dispose
|
|
11
16
|
* function with the error and throw the error.
|
|
17
|
+
* @param layer1 - The name of the first layer.
|
|
18
|
+
* @param layer2 - The name of the second layer.
|
|
19
|
+
* @param compatDetailsLayer1 - The compatibility details of the first layer.
|
|
20
|
+
* @param compatSupportRequirementsLayer1 - The support requirements that the second layer must meet to be compatible
|
|
21
|
+
* with the first layer.
|
|
22
|
+
* @param maybeCompatDetailsLayer2 - The compatibility details of the second layer. This can be undefined if the
|
|
23
|
+
* second layer does not provide compatibility details.
|
|
24
|
+
* @param disposeFn - A function that will be called with the error if the layers are incompatible.
|
|
25
|
+
* @param mc - The monitoring context for logging and reading configuration.
|
|
26
|
+
* @param strictCompatibilityCheck - If true, the function will use default compatibility details for the second layer if
|
|
27
|
+
* they are missing and use it for validation.
|
|
28
|
+
* If false, it will skip the compatibility check if the details are missing and just log an error.
|
|
29
|
+
* Defaults to false.
|
|
12
30
|
*
|
|
13
31
|
* @internal
|
|
14
32
|
*/
|
|
15
|
-
export declare function validateLayerCompatibility(layer1: FluidLayer, layer2: FluidLayer, compatDetailsLayer1: Pick<ILayerCompatDetails, "pkgVersion" | "generation">, compatSupportRequirementsLayer1: ILayerCompatSupportRequirements, maybeCompatDetailsLayer2: ILayerCompatDetails | undefined, disposeFn: (error?: IErrorBase) => void,
|
|
33
|
+
export declare function validateLayerCompatibility(layer1: FluidLayer, layer2: FluidLayer, compatDetailsLayer1: Pick<ILayerCompatDetails, "pkgVersion" | "generation">, compatSupportRequirementsLayer1: ILayerCompatSupportRequirements, maybeCompatDetailsLayer2: ILayerCompatDetails | undefined, disposeFn: (error?: IErrorBase) => void, mc: MonitoringContext, strictCompatibilityCheck?: boolean): void;
|
|
16
34
|
//# sourceMappingURL=layerCompatError.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layerCompatError.d.ts","sourceRoot":"","sources":["../src/layerCompatError.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAEN,KAAK,UAAU,EACf,KAAK,mBAAmB,EACxB,KAAK,+BAA+B,EACpC,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"layerCompatError.d.ts","sourceRoot":"","sources":["../src/layerCompatError.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAEN,KAAK,UAAU,EACf,KAAK,mBAAmB,EACxB,KAAK,+BAA+B,EACpC,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iCAAiC,CAAC;AAElE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGrD;;;GAGG;AACH,eAAO,MAAM,0BAA0B,kCAAkC,CAAC;AAe1E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,0BAA0B,CACzC,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,UAAU,EAClB,mBAAmB,EAAE,IAAI,CAAC,mBAAmB,EAAE,YAAY,GAAG,YAAY,CAAC,EAC3E,+BAA+B,EAAE,+BAA+B,EAChE,wBAAwB,EAAE,mBAAmB,GAAG,SAAS,EACzD,SAAS,EAAE,CAAC,KAAK,CAAC,EAAE,UAAU,KAAK,IAAI,EACvC,EAAE,EAAE,iBAAiB,EACrB,wBAAwB,GAAE,OAAe,GACvC,IAAI,CAiFN"}
|
package/lib/layerCompatError.js
CHANGED
|
@@ -4,14 +4,43 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { checkLayerCompatibility, } from "@fluid-internal/client-utils";
|
|
6
6
|
import { LayerIncompatibilityError } from "./error.js";
|
|
7
|
+
/**
|
|
8
|
+
* The config key to disable layer compatibility validation.
|
|
9
|
+
* @internal
|
|
10
|
+
*/
|
|
11
|
+
export const allowIncompatibleLayersKey = "Fluid.AllowIncompatibleLayers";
|
|
12
|
+
/**
|
|
13
|
+
* Tracks whether the event is logged when failing on layer incompatibility is bypassed via global config.
|
|
14
|
+
* This is used to ensure that the bypass event is only logged once per session so it does not flood telemetry.
|
|
15
|
+
*/
|
|
16
|
+
let globalBypassLogged = false;
|
|
17
|
+
/**
|
|
18
|
+
* Tracks whether the event is logged when failing on layer incompatibility is bypassed due to missing
|
|
19
|
+
* compatibility details for each layer pair.
|
|
20
|
+
* This is used to ensure that the bypass event is only logged once per layer pair so it does not flood telemetry.
|
|
21
|
+
*/
|
|
22
|
+
const strictCheckBypassLoggedForPair = new Set();
|
|
7
23
|
/**
|
|
8
24
|
* Validates the compatibility between two layers using their compatibility details and support requirements.
|
|
9
|
-
* If the layers are incompatible, it logs
|
|
25
|
+
* If the layers are incompatible, it logs a "LayerIncompatibilityError" error event. It will also call the dispose
|
|
10
26
|
* function with the error and throw the error.
|
|
27
|
+
* @param layer1 - The name of the first layer.
|
|
28
|
+
* @param layer2 - The name of the second layer.
|
|
29
|
+
* @param compatDetailsLayer1 - The compatibility details of the first layer.
|
|
30
|
+
* @param compatSupportRequirementsLayer1 - The support requirements that the second layer must meet to be compatible
|
|
31
|
+
* with the first layer.
|
|
32
|
+
* @param maybeCompatDetailsLayer2 - The compatibility details of the second layer. This can be undefined if the
|
|
33
|
+
* second layer does not provide compatibility details.
|
|
34
|
+
* @param disposeFn - A function that will be called with the error if the layers are incompatible.
|
|
35
|
+
* @param mc - The monitoring context for logging and reading configuration.
|
|
36
|
+
* @param strictCompatibilityCheck - If true, the function will use default compatibility details for the second layer if
|
|
37
|
+
* they are missing and use it for validation.
|
|
38
|
+
* If false, it will skip the compatibility check if the details are missing and just log an error.
|
|
39
|
+
* Defaults to false.
|
|
11
40
|
*
|
|
12
41
|
* @internal
|
|
13
42
|
*/
|
|
14
|
-
export function validateLayerCompatibility(layer1, layer2, compatDetailsLayer1, compatSupportRequirementsLayer1, maybeCompatDetailsLayer2, disposeFn,
|
|
43
|
+
export function validateLayerCompatibility(layer1, layer2, compatDetailsLayer1, compatSupportRequirementsLayer1, maybeCompatDetailsLayer2, disposeFn, mc, strictCompatibilityCheck = false) {
|
|
15
44
|
const layerCheckResult = checkLayerCompatibility(compatSupportRequirementsLayer1, maybeCompatDetailsLayer2);
|
|
16
45
|
if (!layerCheckResult.isCompatible) {
|
|
17
46
|
const coreProperties = {
|
|
@@ -34,7 +63,38 @@ export function validateLayerCompatibility(layer1, layer2, compatDetailsLayer1,
|
|
|
34
63
|
...coreProperties,
|
|
35
64
|
details: JSON.stringify(detailedProperties),
|
|
36
65
|
});
|
|
37
|
-
|
|
66
|
+
if (mc.config.getBoolean(allowIncompatibleLayersKey) === true) {
|
|
67
|
+
// If the validation is explicitly disabled via config, do not fail. This config provides a way to bypass
|
|
68
|
+
// compatibility validation while this feature is being rolled out.
|
|
69
|
+
if (!globalBypassLogged) {
|
|
70
|
+
// This event is only logged once per session to avoid flooding telemetry.
|
|
71
|
+
globalBypassLogged = true;
|
|
72
|
+
mc.logger.sendTelemetryEvent({
|
|
73
|
+
eventName: "LayerIncompatibilityDetectedButBypassed",
|
|
74
|
+
reason: `${allowIncompatibleLayersKey} config is set to true`,
|
|
75
|
+
}, error);
|
|
76
|
+
}
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (maybeCompatDetailsLayer2 === undefined && !strictCompatibilityCheck) {
|
|
80
|
+
// If there is no compatibility details for layer2 and strictCompatibilityCheck is false, do not fail.
|
|
81
|
+
// There can be a couple of scenarios where this can happen:
|
|
82
|
+
// 1. layer2's version is older than the version where compatibility enforcement was introduced. In this
|
|
83
|
+
// case, the behavior is the same as before compatibility enforcement was introduced.
|
|
84
|
+
// 2. layer2 has a custom implementation which doesn't provide compatibility details. In this case,
|
|
85
|
+
// we don't know for sure that it is incompatible. It may fail at a later point when it tries to use
|
|
86
|
+
// some feature that the Runtime doesn't support.
|
|
87
|
+
if (!strictCheckBypassLoggedForPair.has(`${layer1}-${layer2}`)) {
|
|
88
|
+
// This event is only logged once per session per layer combination to avoid flooding telemetry.
|
|
89
|
+
strictCheckBypassLoggedForPair.add(`${layer1}-${layer2}`);
|
|
90
|
+
mc.logger.sendTelemetryEvent({
|
|
91
|
+
eventName: "LayerIncompatibilityDetectedButBypassed",
|
|
92
|
+
reason: `No compatibility details provided for ${layer2} and strictCompatibilityCheck is false`,
|
|
93
|
+
}, error);
|
|
94
|
+
}
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
mc.logger.sendErrorEvent({
|
|
38
98
|
eventName: "LayerIncompatibilityError",
|
|
39
99
|
}, error);
|
|
40
100
|
disposeFn(error);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layerCompatError.js","sourceRoot":"","sources":["../src/layerCompatError.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACN,uBAAuB,GAIvB,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"layerCompatError.js","sourceRoot":"","sources":["../src/layerCompatError.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tcheckLayerCompatibility,\n\ttype FluidLayer,\n\ttype ILayerCompatDetails,\n\ttype ILayerCompatSupportRequirements,\n} from \"@fluid-internal/client-utils\";\nimport type { IErrorBase } from \"@fluidframework/core-interfaces\";\n\nimport type { MonitoringContext } from \"./config.js\";\nimport { LayerIncompatibilityError } from \"./error.js\";\n\n/**\n * The config key to disable layer compatibility validation.\n * @internal\n */\nexport const allowIncompatibleLayersKey = \"Fluid.AllowIncompatibleLayers\";\n\n/**\n * Tracks whether the event is logged when failing on layer incompatibility is bypassed via global config.\n * This is used to ensure that the bypass event is only logged once per session so it does not flood telemetry.\n */\nlet globalBypassLogged = false;\n\n/**\n * Tracks whether the event is logged when failing on layer incompatibility is bypassed due to missing\n * compatibility details for each layer pair.\n * This is used to ensure that the bypass event is only logged once per layer pair so it does not flood telemetry.\n */\nconst strictCheckBypassLoggedForPair: Set<string> = new Set<string>();\n\n/**\n * Validates the compatibility between two layers using their compatibility details and support requirements.\n * If the layers are incompatible, it logs a \"LayerIncompatibilityError\" error event. It will also call the dispose\n * function with the error and throw the error.\n * @param layer1 - The name of the first layer.\n * @param layer2 - The name of the second layer.\n * @param compatDetailsLayer1 - The compatibility details of the first layer.\n * @param compatSupportRequirementsLayer1 - The support requirements that the second layer must meet to be compatible\n * with the first layer.\n * @param maybeCompatDetailsLayer2 - The compatibility details of the second layer. This can be undefined if the\n * second layer does not provide compatibility details.\n * @param disposeFn - A function that will be called with the error if the layers are incompatible.\n * @param mc - The monitoring context for logging and reading configuration.\n * @param strictCompatibilityCheck - If true, the function will use default compatibility details for the second layer if\n * they are missing and use it for validation.\n * If false, it will skip the compatibility check if the details are missing and just log an error.\n * Defaults to false.\n *\n * @internal\n */\nexport function validateLayerCompatibility(\n\tlayer1: FluidLayer,\n\tlayer2: FluidLayer,\n\tcompatDetailsLayer1: Pick<ILayerCompatDetails, \"pkgVersion\" | \"generation\">,\n\tcompatSupportRequirementsLayer1: ILayerCompatSupportRequirements,\n\tmaybeCompatDetailsLayer2: ILayerCompatDetails | undefined,\n\tdisposeFn: (error?: IErrorBase) => void,\n\tmc: MonitoringContext,\n\tstrictCompatibilityCheck: boolean = false,\n): void {\n\tconst layerCheckResult = checkLayerCompatibility(\n\t\tcompatSupportRequirementsLayer1,\n\t\tmaybeCompatDetailsLayer2,\n\t);\n\tif (!layerCheckResult.isCompatible) {\n\t\tconst coreProperties = {\n\t\t\tlayer: layer1,\n\t\t\tincompatibleLayer: layer2,\n\t\t\tlayerVersion: compatDetailsLayer1.pkgVersion,\n\t\t\tincompatibleLayerVersion: maybeCompatDetailsLayer2?.pkgVersion ?? \"unknown\",\n\t\t\tcompatibilityRequirementsInMonths:\n\t\t\t\tcompatDetailsLayer1.generation -\n\t\t\t\tcompatSupportRequirementsLayer1.minSupportedGeneration,\n\t\t\tactualDifferenceInMonths:\n\t\t\t\tcompatDetailsLayer1.generation - (maybeCompatDetailsLayer2?.generation ?? 0),\n\t\t};\n\t\tconst detailedProperties = {\n\t\t\tlayerGeneration: compatDetailsLayer1.generation,\n\t\t\tincompatibleLayerGeneration: maybeCompatDetailsLayer2?.generation,\n\t\t\tminSupportedGeneration: compatSupportRequirementsLayer1.minSupportedGeneration,\n\t\t\tisGenerationCompatible: layerCheckResult.isGenerationCompatible,\n\t\t\tunsupportedFeatures: layerCheckResult.unsupportedFeatures,\n\t\t};\n\n\t\tconst error = new LayerIncompatibilityError(\n\t\t\t`The versions of the ${layer1} and ${layer2} are not compatible`,\n\t\t\t{\n\t\t\t\t...coreProperties,\n\t\t\t\tdetails: JSON.stringify(detailedProperties),\n\t\t\t},\n\t\t);\n\n\t\tif (mc.config.getBoolean(allowIncompatibleLayersKey) === true) {\n\t\t\t// If the validation is explicitly disabled via config, do not fail. This config provides a way to bypass\n\t\t\t// compatibility validation while this feature is being rolled out.\n\t\t\tif (!globalBypassLogged) {\n\t\t\t\t// This event is only logged once per session to avoid flooding telemetry.\n\t\t\t\tglobalBypassLogged = true;\n\t\t\t\tmc.logger.sendTelemetryEvent(\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"LayerIncompatibilityDetectedButBypassed\",\n\t\t\t\t\t\treason: `${allowIncompatibleLayersKey} config is set to true`,\n\t\t\t\t\t},\n\t\t\t\t\terror,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tif (maybeCompatDetailsLayer2 === undefined && !strictCompatibilityCheck) {\n\t\t\t// If there is no compatibility details for layer2 and strictCompatibilityCheck is false, do not fail.\n\t\t\t// There can be a couple of scenarios where this can happen:\n\t\t\t// 1. layer2's version is older than the version where compatibility enforcement was introduced. In this\n\t\t\t// case, the behavior is the same as before compatibility enforcement was introduced.\n\t\t\t// 2. layer2 has a custom implementation which doesn't provide compatibility details. In this case,\n\t\t\t// we don't know for sure that it is incompatible. It may fail at a later point when it tries to use\n\t\t\t// some feature that the Runtime doesn't support.\n\t\t\tif (!strictCheckBypassLoggedForPair.has(`${layer1}-${layer2}`)) {\n\t\t\t\t// This event is only logged once per session per layer combination to avoid flooding telemetry.\n\t\t\t\tstrictCheckBypassLoggedForPair.add(`${layer1}-${layer2}`);\n\t\t\t\tmc.logger.sendTelemetryEvent(\n\t\t\t\t\t{\n\t\t\t\t\t\teventName: \"LayerIncompatibilityDetectedButBypassed\",\n\t\t\t\t\t\treason: `No compatibility details provided for ${layer2} and strictCompatibilityCheck is false`,\n\t\t\t\t\t},\n\t\t\t\t\terror,\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tmc.logger.sendErrorEvent(\n\t\t\t{\n\t\t\t\teventName: \"LayerIncompatibilityError\",\n\t\t\t},\n\t\t\terror,\n\t\t);\n\t\tdisposeFn(error);\n\t\tthrow error;\n\t}\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/telemetry-utils",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.80.0",
|
|
4
4
|
"description": "Collection of telemetry relates utilities for Fluid",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -69,36 +69,36 @@
|
|
|
69
69
|
"temp-directory": "nyc/.nyc_output"
|
|
70
70
|
},
|
|
71
71
|
"dependencies": {
|
|
72
|
-
"@fluid-internal/client-utils": "~2.
|
|
73
|
-
"@fluidframework/core-interfaces": "~2.
|
|
74
|
-
"@fluidframework/core-utils": "~2.
|
|
75
|
-
"@fluidframework/driver-definitions": "~2.
|
|
72
|
+
"@fluid-internal/client-utils": "~2.80.0",
|
|
73
|
+
"@fluidframework/core-interfaces": "~2.80.0",
|
|
74
|
+
"@fluidframework/core-utils": "~2.80.0",
|
|
75
|
+
"@fluidframework/driver-definitions": "~2.80.0",
|
|
76
76
|
"debug": "^4.3.4",
|
|
77
77
|
"uuid": "^11.1.0"
|
|
78
78
|
},
|
|
79
79
|
"devDependencies": {
|
|
80
|
-
"@arethetypeswrong/cli": "^0.
|
|
80
|
+
"@arethetypeswrong/cli": "^0.18.2",
|
|
81
81
|
"@biomejs/biome": "~1.9.3",
|
|
82
|
-
"@fluid-internal/mocha-test-setup": "~2.
|
|
83
|
-
"@fluid-tools/build-cli": "^0.
|
|
82
|
+
"@fluid-internal/mocha-test-setup": "~2.80.0",
|
|
83
|
+
"@fluid-tools/build-cli": "^0.62.0",
|
|
84
84
|
"@fluidframework/build-common": "^2.0.3",
|
|
85
|
-
"@fluidframework/build-tools": "^0.
|
|
86
|
-
"@fluidframework/eslint-config-fluid": "~2.
|
|
87
|
-
"@fluidframework/telemetry-utils-previous": "npm:@fluidframework/telemetry-utils@2.
|
|
85
|
+
"@fluidframework/build-tools": "^0.62.0",
|
|
86
|
+
"@fluidframework/eslint-config-fluid": "~2.80.0",
|
|
87
|
+
"@fluidframework/telemetry-utils-previous": "npm:@fluidframework/telemetry-utils@2.74.0",
|
|
88
88
|
"@microsoft/api-extractor": "7.52.11",
|
|
89
89
|
"@types/debug": "^4.1.5",
|
|
90
90
|
"@types/mocha": "^10.0.10",
|
|
91
91
|
"@types/node": "^18.19.0",
|
|
92
92
|
"@types/sinon": "^17.0.3",
|
|
93
93
|
"c8": "^10.1.3",
|
|
94
|
-
"concurrently": "^
|
|
94
|
+
"concurrently": "^9.2.1",
|
|
95
95
|
"copyfiles": "^2.4.1",
|
|
96
|
-
"cross-env": "^
|
|
97
|
-
"eslint": "~
|
|
96
|
+
"cross-env": "^10.1.0",
|
|
97
|
+
"eslint": "~9.39.1",
|
|
98
98
|
"jiti": "^2.6.1",
|
|
99
99
|
"mocha": "^10.8.2",
|
|
100
100
|
"mocha-multi-reporters": "^1.5.1",
|
|
101
|
-
"rimraf": "^
|
|
101
|
+
"rimraf": "^6.1.2",
|
|
102
102
|
"sinon": "^18.0.1",
|
|
103
103
|
"typescript": "~5.4.5"
|
|
104
104
|
},
|
package/src/error.ts
CHANGED
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
import type { IErrorBase, ITelemetryBaseProperties } from "@fluidframework/core-interfaces";
|
|
7
7
|
import {
|
|
8
8
|
FluidErrorTypes,
|
|
9
|
-
FluidErrorTypesAlpha,
|
|
10
9
|
type IGenericError,
|
|
11
10
|
type ILayerIncompatibilityError,
|
|
12
11
|
type IUsageError,
|
|
@@ -235,7 +234,7 @@ export class LayerIncompatibilityError
|
|
|
235
234
|
extends LoggingError
|
|
236
235
|
implements ILayerIncompatibilityError
|
|
237
236
|
{
|
|
238
|
-
public readonly errorType =
|
|
237
|
+
public readonly errorType = FluidErrorTypes.layerIncompatibilityError;
|
|
239
238
|
public readonly layer: string;
|
|
240
239
|
public readonly layerVersion: string;
|
|
241
240
|
public readonly incompatibleLayer: string;
|
package/src/fluidErrorBase.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import type { ITelemetryBaseProperties } from "@fluidframework/core-interfaces";
|
|
7
7
|
import {
|
|
8
|
-
|
|
8
|
+
FluidErrorTypes,
|
|
9
9
|
type ILayerIncompatibilityError,
|
|
10
10
|
} from "@fluidframework/core-interfaces/internal";
|
|
11
11
|
|
|
@@ -123,7 +123,5 @@ export function isFluidError(error: unknown): error is IFluidErrorBase {
|
|
|
123
123
|
export function isLayerIncompatibilityError(
|
|
124
124
|
error: unknown,
|
|
125
125
|
): error is ILayerIncompatibilityError {
|
|
126
|
-
return (
|
|
127
|
-
isFluidError(error) && error.errorType === FluidErrorTypesAlpha.layerIncompatibilityError
|
|
128
|
-
);
|
|
126
|
+
return isFluidError(error) && error.errorType === FluidErrorTypes.layerIncompatibilityError;
|
|
129
127
|
}
|
package/src/index.ts
CHANGED
|
@@ -98,4 +98,4 @@ export type {
|
|
|
98
98
|
TelemetryEventCategory,
|
|
99
99
|
} from "./telemetryTypes.js";
|
|
100
100
|
export { TelemetryEventBatcher } from "./telemetryEventBatcher.js";
|
|
101
|
-
export { validateLayerCompatibility } from "./layerCompatError.js";
|
|
101
|
+
export { allowIncompatibleLayersKey, validateLayerCompatibility } from "./layerCompatError.js";
|
package/src/layerCompatError.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
},
|