@fluidframework/telemetry-utils 2.61.0-356132 → 2.61.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 +8 -0
- package/dist/errorLogging.d.ts +1 -0
- package/dist/errorLogging.d.ts.map +1 -1
- package/dist/errorLogging.js +4 -0
- package/dist/errorLogging.js.map +1 -1
- package/dist/fluidErrorBase.d.ts +13 -0
- package/dist/fluidErrorBase.d.ts.map +1 -1
- package/dist/fluidErrorBase.js.map +1 -1
- package/lib/errorLogging.d.ts +1 -0
- package/lib/errorLogging.d.ts.map +1 -1
- package/lib/errorLogging.js +4 -0
- package/lib/errorLogging.js.map +1 -1
- package/lib/fluidErrorBase.d.ts +13 -0
- package/lib/fluidErrorBase.d.ts.map +1 -1
- package/lib/fluidErrorBase.js.map +1 -1
- package/package.json +6 -6
- package/src/errorLogging.ts +7 -0
- package/src/fluidErrorBase.ts +14 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# @fluidframework/telemetry-utils
|
|
2
2
|
|
|
3
|
+
## 2.61.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Wrapped errors preserved as `cause` property ([#25485](https://github.com/microsoft/FluidFramework/pull/25485)) [c69d56d2b2](https://github.com/microsoft/FluidFramework/commit/c69d56d2b210e82cb42cb4ec8f8b6d3f8ce6c9db)
|
|
8
|
+
|
|
9
|
+
`IFluidErrorBase` (internal basis for FluidFramework client errors) declares `cause` property matching ES2022 lib (whether targeted or not). When an error is wrapped, `cause` will be set to the originating error (which may or may not itself be an `Error`).
|
|
10
|
+
|
|
3
11
|
## 2.60.0
|
|
4
12
|
|
|
5
13
|
Dependency updates only.
|
package/dist/errorLogging.d.ts
CHANGED
|
@@ -126,6 +126,7 @@ export declare const getCircularReplacer: () => ((key: string, value: unknown) =
|
|
|
126
126
|
*/
|
|
127
127
|
export declare class LoggingError extends Error implements ILoggingError, Omit<IFluidErrorBase, "errorType"> {
|
|
128
128
|
private readonly omitPropsFromLogging;
|
|
129
|
+
cause?: unknown;
|
|
129
130
|
private _errorInstanceId;
|
|
130
131
|
get errorInstanceId(): string;
|
|
131
132
|
overwriteErrorInstanceId(id: string): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errorLogging.d.ts","sourceRoot":"","sources":["../src/errorLogging.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,EAAE,MAAM,iCAAiC,CAAC;AACxF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0CAA0C,CAAC;AAG9E,OAAO,EAAE,KAAK,eAAe,EAAoC,MAAM,qBAAqB,CAAC;AAE7F,OAAO,KAAK,EACX,mBAAmB,EACnB,uBAAuB,EACvB,6BAA6B,EAC7B,MAAM,qBAAqB,CAAC;AAS7B;;;;GAIG;AACH,wBAAgB,6BAA6B,CAC5C,KAAK,EAAE,OAAO,EACd,aAAa,EAAE,OAAO,GACpB;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B,CAoCA;AAED;;;;GAIG;AACH,eAAO,MAAM,eAAe,MAAO,OAAO,uBACkC,CAAC;AAgB7E;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACtC;;OAEG;IACH,KAAK,CAAC,EAAE,wBAAwB,CAAC;CACjC;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC7B,KAAK,EAAE,OAAO,EACd,WAAW,GAAE,sBAA2B,GACtC,eAAe,CAqDjB;AAID;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,KAAK,CAuBtE;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE1E;AAED;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,YAAY,EAC/C,UAAU,EAAE,OAAO,EACnB,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,CAAC,GAChC,CAAC,
|
|
1
|
+
{"version":3,"file":"errorLogging.d.ts","sourceRoot":"","sources":["../src/errorLogging.ts"],"names":[],"mappings":"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"}
|
package/dist/errorLogging.js
CHANGED
|
@@ -183,6 +183,7 @@ exports.generateStack = generateStack;
|
|
|
183
183
|
function wrapError(innerError, newErrorFn) {
|
|
184
184
|
const { message, stack } = extractLogSafeErrorProperties(innerError, false /* sanitizeStack */);
|
|
185
185
|
const newError = newErrorFn(message);
|
|
186
|
+
newError.cause = innerError;
|
|
186
187
|
if (stack !== undefined) {
|
|
187
188
|
overwriteStack(newError, stack);
|
|
188
189
|
}
|
|
@@ -334,6 +335,9 @@ class LoggingError extends Error {
|
|
|
334
335
|
// Don't log this list itself, or the private _errorInstanceId
|
|
335
336
|
omitPropsFromLogging.add("omitPropsFromLogging");
|
|
336
337
|
omitPropsFromLogging.add("_errorInstanceId");
|
|
338
|
+
// Nor log the unknown cause property, which could be anything.
|
|
339
|
+
// Core elements of "cause" are already promoted by wrapError.
|
|
340
|
+
omitPropsFromLogging.add("cause");
|
|
337
341
|
if (props) {
|
|
338
342
|
this.addTelemetryProperties(props);
|
|
339
343
|
}
|
package/dist/errorLogging.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errorLogging.js","sourceRoot":"","sources":["../src/errorLogging.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 { ITelemetryBaseProperties, Tagged } from \"@fluidframework/core-interfaces\";\nimport type { ILoggingError } from \"@fluidframework/core-interfaces/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport { type IFluidErrorBase, hasErrorInstanceId, isFluidError } from \"./fluidErrorBase.js\";\nimport { convertToBasePropertyType } from \"./logger.js\";\nimport type {\n\tITelemetryLoggerExt,\n\tITelemetryPropertiesExt,\n\tTelemetryEventPropertyTypeExt,\n} from \"./telemetryTypes.js\";\n\n/**\n * Determines if the provided value is an object but neither null nor an array.\n */\nconst isRegularObject = (value: unknown): boolean => {\n\treturn value !== null && !Array.isArray(value) && typeof value === \"object\";\n};\n\n/**\n * Inspect the given error for common \"safe\" props and return them.\n *\n * @internal\n */\nexport function extractLogSafeErrorProperties(\n\terror: unknown,\n\tsanitizeStack: boolean,\n): {\n\tmessage: string;\n\terrorType?: string | undefined;\n\tstack?: string | undefined;\n} {\n\tconst removeMessageFromStack = (stack: string, errorName?: string): string => {\n\t\tif (!sanitizeStack) {\n\t\t\treturn stack;\n\t\t}\n\t\tconst stackFrames = stack.split(\"\\n\");\n\t\tstackFrames.shift(); // Remove \"[ErrorName]: [ErrorMessage]\"\n\t\tif (errorName !== undefined) {\n\t\t\tstackFrames.unshift(errorName); // Add \"[ErrorName]\"\n\t\t}\n\t\treturn stackFrames.join(\"\\n\");\n\t};\n\n\tconst message =\n\t\ttypeof (error as Partial<Error>)?.message === \"string\"\n\t\t\t? (error as Error).message\n\t\t\t: String(error);\n\n\tconst safeProps: { message: string; errorType?: string; stack?: string } = {\n\t\tmessage,\n\t};\n\n\tif (isRegularObject(error)) {\n\t\tconst { errorType, stack, name } = error as Partial<IFluidErrorBase>;\n\n\t\tif (typeof errorType === \"string\") {\n\t\t\tsafeProps.errorType = errorType;\n\t\t}\n\n\t\tif (typeof stack === \"string\") {\n\t\t\tconst errorName = typeof name === \"string\" ? name : undefined;\n\t\t\tsafeProps.stack = removeMessageFromStack(stack, errorName);\n\t\t}\n\t}\n\n\treturn safeProps;\n}\n\n/**\n * Type-guard for {@link @fluidframework/core-interfaces#ILoggingError}.\n *\n * @internal\n */\nexport const isILoggingError = (x: unknown): x is ILoggingError =>\n\ttypeof (x as Partial<ILoggingError>)?.getTelemetryProperties === \"function\";\n\n/**\n * Copy props from source onto target, but do not overwrite an existing prop that matches\n */\nfunction copyProps(\n\ttarget: ITelemetryPropertiesExt | LoggingError,\n\tsource: ITelemetryPropertiesExt,\n): void {\n\tfor (const [key, value] of Object.entries(source)) {\n\t\tif (target[key] === undefined) {\n\t\t\ttarget[key] = value;\n\t\t}\n\t}\n}\n\n/**\n * Metadata to annotate an error object when annotating or normalizing it\n *\n * @internal\n */\nexport interface IFluidErrorAnnotations {\n\t/**\n\t * Telemetry props to log with the error\n\t */\n\tprops?: ITelemetryBaseProperties;\n}\n\n/**\n * Normalize the given error yielding a valid Fluid Error\n * @returns A valid Fluid Error with any provided annotations applied\n * @param error - The error to normalize\n * @param annotations - Annotations to apply to the normalized error\n *\n * @internal\n */\nexport function normalizeError(\n\terror: unknown,\n\tannotations: IFluidErrorAnnotations = {},\n): IFluidErrorBase {\n\tif (isFluidError(error)) {\n\t\t// We can simply add the telemetry props to the error and return it\n\t\terror.addTelemetryProperties(annotations.props ?? {});\n\t\treturn error;\n\t}\n\n\t// We have to construct a new Fluid Error, copying safe properties over\n\tconst { message, stack } = extractLogSafeErrorProperties(error, false /* sanitizeStack */);\n\tconst fluidError: IFluidErrorBase = new NormalizedLoggingError({\n\t\tmessage,\n\t\tstack,\n\t});\n\n\t// We need to preserve these properties which are used in a non-typesafe way throughout driver code (see #8743)\n\t// Anywhere they are set should be on a valid Fluid Error that would have been returned above,\n\t// but we can't prove it with the types, so adding this defensive measure.\n\tif (typeof error === \"object\" && error !== null) {\n\t\tconst maybeHasRetry: Partial<Record<\"canRetry\" | \"retryAfterSeconds\", unknown>> = error;\n\t\tlet retryProps: Partial<Record<\"canRetry\" | \"retryAfterSeconds\", unknown>> | undefined;\n\t\tif (\"canRetry\" in error) {\n\t\t\tretryProps ??= {};\n\t\t\tretryProps.canRetry = maybeHasRetry.canRetry;\n\t\t}\n\t\tif (\"retryAfterSeconds\" in error) {\n\t\t\tretryProps ??= {};\n\t\t\tretryProps.retryAfterSeconds = maybeHasRetry.retryAfterSeconds;\n\t\t}\n\t\tif (retryProps !== undefined) {\n\t\t\tObject.assign(fluidError, retryProps);\n\t\t}\n\t}\n\n\tif (typeof error !== \"object\") {\n\t\t// This is only interesting for non-objects\n\t\tfluidError.addTelemetryProperties({ typeofError: typeof error });\n\t}\n\n\tconst errorTelemetryProps = LoggingError.typeCheck(error)\n\t\t? error.getTelemetryProperties()\n\t\t: {\n\t\t\t\tuntrustedOrigin: 1, // This will let us filter errors that did not originate from our own codebase\n\t\t\t\t// FUTURE: Once 2.0 becomes LTS, switch to this more explicit property name\n\t\t\t\t// Consider using a string to distinguish cases like \"dependency\" v. \"callback\"\n\t\t\t\t// errorRunningExternalCode: 1,\n\t\t\t};\n\n\tfluidError.addTelemetryProperties({\n\t\t...errorTelemetryProps,\n\t\t...annotations.props,\n\t});\n\n\treturn fluidError;\n}\n\nlet stackPopulatedOnCreation: boolean | undefined;\n\n/**\n * The purpose of this function is to provide ability to capture stack context quickly.\n * Accessing new Error().stack is slow, and the slowest part is accessing stack property itself.\n * There are scenarios where we generate error with stack, but error is handled in most cases and\n * stack property is not accessed.\n * For such cases it's better to not read stack property right away, but rather delay it until / if it's needed\n * Some browsers will populate stack right away, others require throwing Error, so we do auto-detection on the fly.\n * @param stackTraceLimit - stack trace limit for an error\n * @returns Error object that has stack populated.\n *\n * @internal\n */\nexport function generateErrorWithStack(stackTraceLimit?: number): Error {\n\tconst ErrorConfig = Error as unknown as { stackTraceLimit: number };\n\tconst originalStackTraceLimit = ErrorConfig.stackTraceLimit;\n\tif (stackTraceLimit !== undefined) {\n\t\tErrorConfig.stackTraceLimit = stackTraceLimit;\n\t}\n\tconst err = new Error(\"<<generated stack>>\");\n\n\tif (stackPopulatedOnCreation === undefined) {\n\t\tstackPopulatedOnCreation = err.stack !== undefined;\n\t}\n\n\tif (stackPopulatedOnCreation) {\n\t\tErrorConfig.stackTraceLimit = originalStackTraceLimit;\n\t\treturn err;\n\t}\n\n\ttry {\n\t\tthrow err;\n\t} catch (error) {\n\t\tErrorConfig.stackTraceLimit = originalStackTraceLimit;\n\t\treturn error as Error;\n\t}\n}\n\n/**\n * Generate a stack at this callsite as if an error were thrown from here.\n * @param stackTraceLimit - stack trace limit for an error\n * @returns the callstack (does not throw)\n *\n * @internal\n */\nexport function generateStack(stackTraceLimit?: number): string | undefined {\n\treturn generateErrorWithStack(stackTraceLimit).stack;\n}\n\n/**\n * Create a new error using newErrorFn, wrapping and caused by the given unknown error.\n * Copies the inner error's stack, errorInstanceId and telemetry props over to the new error if present\n * @param innerError - An error from untrusted/unknown origins\n * @param newErrorFn - callback that will create a new error given the original error's message\n * @returns A new error object \"wrapping\" the given error\n *\n * @internal\n */\nexport function wrapError<T extends LoggingError>(\n\tinnerError: unknown,\n\tnewErrorFn: (message: string) => T,\n): T {\n\tconst { message, stack } = extractLogSafeErrorProperties(\n\t\tinnerError,\n\t\tfalse /* sanitizeStack */,\n\t);\n\n\tconst newError = newErrorFn(message);\n\n\tif (stack !== undefined) {\n\t\toverwriteStack(newError, stack);\n\t}\n\n\t// Mark external errors with untrustedOrigin flag\n\tif (isExternalError(innerError)) {\n\t\tnewError.addTelemetryProperties({\n\t\t\tuntrustedOrigin: 1,\n\t\t\t// FUTURE: Once 2.0 becomes LTS, switch to this more explicit property name\n\t\t\t// Consider using a string to distinguish cases like \"dependency\" v. \"callback\"\n\t\t\t// errorRunningExternalCode: 1,\n\t\t});\n\t}\n\n\t// Reuse errorInstanceId\n\tif (hasErrorInstanceId(innerError)) {\n\t\tnewError.overwriteErrorInstanceId(innerError.errorInstanceId);\n\n\t\t// For \"back-compat\" in the logs\n\t\tnewError.addTelemetryProperties({ innerErrorInstanceId: innerError.errorInstanceId });\n\t}\n\n\t// Lastly, copy over all other telemetry properties. Note these will not overwrite existing properties\n\t// This will include the untrustedOrigin/errorRunningExternalCode info if the inner error itself was created from an external error\n\tif (isILoggingError(innerError)) {\n\t\tnewError.addTelemetryProperties(innerError.getTelemetryProperties());\n\t}\n\n\treturn newError;\n}\n\n/**\n * The same as wrapError, but also logs the innerError, including the wrapping error's instance ID.\n *\n * @typeParam T - The kind of wrapper error to create.\n *\n * @internal\n */\nexport function wrapErrorAndLog<T extends LoggingError>(\n\tinnerError: unknown,\n\tnewErrorFn: (message: string) => T,\n\tlogger: ITelemetryLoggerExt,\n): T {\n\tconst newError = wrapError(innerError, newErrorFn);\n\n\t// This will match innerError.errorInstanceId if present (see wrapError)\n\tconst errorInstanceId = newError.errorInstanceId;\n\n\t// For \"back-compat\" in the logs\n\tconst wrappedByErrorInstanceId = errorInstanceId;\n\n\tlogger.sendTelemetryEvent(\n\t\t{\n\t\t\teventName: \"WrapError\",\n\t\t\terrorInstanceId,\n\t\t\twrappedByErrorInstanceId,\n\t\t},\n\t\tinnerError,\n\t);\n\n\treturn newError;\n}\n\n/**\n * Attempts to overwrite the error's stack\n *\n * There have been reports of certain JS environments where overwriting stack will throw.\n * If that happens, this adds the given stack as the telemetry property \"stack2\"\n *\n * @internal\n */\nexport function overwriteStack(error: IFluidErrorBase | LoggingError, stack: string): void {\n\ttry {\n\t\tObject.assign(error, { stack });\n\t} catch {\n\t\terror.addTelemetryProperties({ stack2: stack });\n\t}\n}\n\n/**\n * True for any error object that is an (optionally normalized) external error\n * False for any error we created and raised within the FF codebase via LoggingError base class,\n * or wrapped in a well-known error type\n *\n * @internal\n */\nexport function isExternalError(error: unknown): boolean {\n\t// LoggingErrors are an internal FF error type. However, an external error can be converted\n\t// into a LoggingError if it is normalized. In this case we must use the untrustedOrigin/errorRunningExternalCode flag to\n\t// determine whether the original error was in fact external.\n\tif (LoggingError.typeCheck(error)) {\n\t\tif ((error as NormalizedLoggingError).errorType === NORMALIZED_ERROR_TYPE) {\n\t\t\tconst props = error.getTelemetryProperties();\n\t\t\t// NOTE: errorRunningExternalCode is not currently used - once this \"read\" code reaches LTS,\n\t\t\t// we can switch to writing this more explicit property\n\t\t\treturn props.untrustedOrigin === 1 || Boolean(props.errorRunningExternalCode);\n\t\t}\n\t\treturn false;\n\t}\n\treturn true;\n}\n\n/**\n * Type guard to identify if a particular telemetry property appears to be a\n * {@link @fluidframework/core-interfaces#Tagged} telemetry property.\n *\n * @internal\n */\nexport function isTaggedTelemetryPropertyValue(\n\tx: Tagged<TelemetryEventPropertyTypeExt> | TelemetryEventPropertyTypeExt,\n): x is Tagged<TelemetryEventPropertyTypeExt> {\n\treturn typeof (x as Partial<Tagged<unknown>>)?.tag === \"string\";\n}\n\n// TODO: Use `unknown` instead (API breaking change)\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/**\n * Borrowed from\n * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cyclic_object_value#examples}\n * Avoids runtime errors with circular references.\n * Not ideal, as will cut values that are not necessarily circular references.\n * Could be improved by implementing Node's util.inspect() for browser (minus all the coloring code)\n *\n * @internal\n */\nexport const getCircularReplacer = (): ((key: string, value: unknown) => any) => {\n\tconst seen = new WeakSet();\n\treturn (key: string, value: unknown): any => {\n\t\tif (typeof value === \"object\" && value !== null) {\n\t\t\tif (seen.has(value)) {\n\t\t\t\treturn \"<removed/circular>\";\n\t\t\t}\n\t\t\tseen.add(value);\n\t\t}\n\t\treturn value;\n\t};\n};\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\n/**\n * Base class for \"trusted\" errors we create, whose properties can generally be logged to telemetry safely.\n * All properties set on the object, or passed in (via the constructor or addTelemetryProperties),\n * will be logged in accordance with their tag, if present.\n *\n * PLEASE take care to avoid setting sensitive data on this object without proper tagging!\n *\n * @internal\n */\nexport class LoggingError\n\textends Error\n\timplements ILoggingError, Omit<IFluidErrorBase, \"errorType\">\n{\n\tprivate _errorInstanceId = uuid();\n\tpublic get errorInstanceId(): string {\n\t\treturn this._errorInstanceId;\n\t}\n\tpublic overwriteErrorInstanceId(id: string): void {\n\t\tthis._errorInstanceId = id;\n\t}\n\n\t/**\n\t * Create a new LoggingError\n\t * @param message - Error message to use for Error base class\n\t * @param props - telemetry props to include on the error for when it's logged\n\t * @param omitPropsFromLogging - properties by name to omit from telemetry props\n\t */\n\tpublic constructor(\n\t\tmessage: string,\n\t\tprops?: ITelemetryBaseProperties,\n\t\tprivate readonly omitPropsFromLogging: Set<string> = new Set(),\n\t) {\n\t\tsuper(message);\n\n\t\t// Don't log this list itself, or the private _errorInstanceId\n\t\tomitPropsFromLogging.add(\"omitPropsFromLogging\");\n\t\tomitPropsFromLogging.add(\"_errorInstanceId\");\n\n\t\tif (props) {\n\t\t\tthis.addTelemetryProperties(props);\n\t\t}\n\t}\n\n\t/**\n\t * Determines if a given object is an instance of a LoggingError\n\t * @param object - any object\n\t * @returns true if the object is an instance of a LoggingError, false if not.\n\t */\n\tpublic static typeCheck(object: unknown): object is LoggingError {\n\t\tif (typeof object === \"object\" && object !== null) {\n\t\t\treturn (\n\t\t\t\ttypeof (object as LoggingError).addTelemetryProperties === \"function\" &&\n\t\t\t\ttypeof (object as LoggingError).getTelemetryProperties === \"function\" &&\n\t\t\t\ttypeof (object as LoggingError).errorInstanceId === \"string\"\n\t\t\t);\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Add additional properties to be logged\n\t */\n\tpublic addTelemetryProperties(props: ITelemetryPropertiesExt): void {\n\t\tcopyProps(this, props);\n\t}\n\n\t/**\n\t * Get all properties fit to be logged to telemetry for this error\n\t */\n\tpublic getTelemetryProperties(): ITelemetryBaseProperties {\n\t\t// Only pick properties fit for telemetry out of all of this object's enumerable properties.\n\t\tconst telemetryProps: ITelemetryBaseProperties = {};\n\t\tfor (const key of Object.keys(this)) {\n\t\t\tif (this.omitPropsFromLogging.has(key)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst val = this[key] as\n\t\t\t\t| TelemetryEventPropertyTypeExt\n\t\t\t\t| Tagged<TelemetryEventPropertyTypeExt>;\n\n\t\t\t// Ensure only valid props get logged, since props of logging error could be in any shape\n\t\t\ttelemetryProps[key] = convertToBasePropertyType(val);\n\t\t}\n\t\t// Ensure a few extra props always exist\n\t\treturn {\n\t\t\t...telemetryProps,\n\t\t\tstack: this.stack,\n\t\t\tmessage: this.message,\n\t\t\terrorInstanceId: this._errorInstanceId,\n\t\t};\n\t}\n}\n\n/**\n * The Error class used when normalizing an external error\n *\n * @internal\n */\nexport const NORMALIZED_ERROR_TYPE = \"genericError\";\n\n/**\n * Subclass of LoggingError returned by normalizeError\n *\n * @internal\n */\nclass NormalizedLoggingError extends LoggingError {\n\t// errorType \"genericError\" is used as a default value throughout the code.\n\t// Note that this matches ContainerErrorTypes/DriverErrorTypes' genericError\n\tpublic readonly errorType = NORMALIZED_ERROR_TYPE;\n\n\tpublic constructor(errorProps: Pick<IFluidErrorBase, \"message\" | \"stack\">) {\n\t\tsuper(errorProps.message);\n\n\t\tif (errorProps.stack !== undefined) {\n\t\t\toverwriteStack(this, errorProps.stack);\n\t\t}\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"errorLogging.js","sourceRoot":"","sources":["../src/errorLogging.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 { ITelemetryBaseProperties, Tagged } from \"@fluidframework/core-interfaces\";\nimport type { ILoggingError } from \"@fluidframework/core-interfaces/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport { type IFluidErrorBase, hasErrorInstanceId, isFluidError } from \"./fluidErrorBase.js\";\nimport { convertToBasePropertyType } from \"./logger.js\";\nimport type {\n\tITelemetryLoggerExt,\n\tITelemetryPropertiesExt,\n\tTelemetryEventPropertyTypeExt,\n} from \"./telemetryTypes.js\";\n\n/**\n * Determines if the provided value is an object but neither null nor an array.\n */\nconst isRegularObject = (value: unknown): boolean => {\n\treturn value !== null && !Array.isArray(value) && typeof value === \"object\";\n};\n\n/**\n * Inspect the given error for common \"safe\" props and return them.\n *\n * @internal\n */\nexport function extractLogSafeErrorProperties(\n\terror: unknown,\n\tsanitizeStack: boolean,\n): {\n\tmessage: string;\n\terrorType?: string | undefined;\n\tstack?: string | undefined;\n} {\n\tconst removeMessageFromStack = (stack: string, errorName?: string): string => {\n\t\tif (!sanitizeStack) {\n\t\t\treturn stack;\n\t\t}\n\t\tconst stackFrames = stack.split(\"\\n\");\n\t\tstackFrames.shift(); // Remove \"[ErrorName]: [ErrorMessage]\"\n\t\tif (errorName !== undefined) {\n\t\t\tstackFrames.unshift(errorName); // Add \"[ErrorName]\"\n\t\t}\n\t\treturn stackFrames.join(\"\\n\");\n\t};\n\n\tconst message =\n\t\ttypeof (error as Partial<Error>)?.message === \"string\"\n\t\t\t? (error as Error).message\n\t\t\t: String(error);\n\n\tconst safeProps: { message: string; errorType?: string; stack?: string } = {\n\t\tmessage,\n\t};\n\n\tif (isRegularObject(error)) {\n\t\tconst { errorType, stack, name } = error as Partial<IFluidErrorBase>;\n\n\t\tif (typeof errorType === \"string\") {\n\t\t\tsafeProps.errorType = errorType;\n\t\t}\n\n\t\tif (typeof stack === \"string\") {\n\t\t\tconst errorName = typeof name === \"string\" ? name : undefined;\n\t\t\tsafeProps.stack = removeMessageFromStack(stack, errorName);\n\t\t}\n\t}\n\n\treturn safeProps;\n}\n\n/**\n * Type-guard for {@link @fluidframework/core-interfaces#ILoggingError}.\n *\n * @internal\n */\nexport const isILoggingError = (x: unknown): x is ILoggingError =>\n\ttypeof (x as Partial<ILoggingError>)?.getTelemetryProperties === \"function\";\n\n/**\n * Copy props from source onto target, but do not overwrite an existing prop that matches\n */\nfunction copyProps(\n\ttarget: ITelemetryPropertiesExt | LoggingError,\n\tsource: ITelemetryPropertiesExt,\n): void {\n\tfor (const [key, value] of Object.entries(source)) {\n\t\tif (target[key] === undefined) {\n\t\t\ttarget[key] = value;\n\t\t}\n\t}\n}\n\n/**\n * Metadata to annotate an error object when annotating or normalizing it\n *\n * @internal\n */\nexport interface IFluidErrorAnnotations {\n\t/**\n\t * Telemetry props to log with the error\n\t */\n\tprops?: ITelemetryBaseProperties;\n}\n\n/**\n * Normalize the given error yielding a valid Fluid Error\n * @returns A valid Fluid Error with any provided annotations applied\n * @param error - The error to normalize\n * @param annotations - Annotations to apply to the normalized error\n *\n * @internal\n */\nexport function normalizeError(\n\terror: unknown,\n\tannotations: IFluidErrorAnnotations = {},\n): IFluidErrorBase {\n\tif (isFluidError(error)) {\n\t\t// We can simply add the telemetry props to the error and return it\n\t\terror.addTelemetryProperties(annotations.props ?? {});\n\t\treturn error;\n\t}\n\n\t// We have to construct a new Fluid Error, copying safe properties over\n\tconst { message, stack } = extractLogSafeErrorProperties(error, false /* sanitizeStack */);\n\tconst fluidError: IFluidErrorBase = new NormalizedLoggingError({\n\t\tmessage,\n\t\tstack,\n\t});\n\n\t// We need to preserve these properties which are used in a non-typesafe way throughout driver code (see #8743)\n\t// Anywhere they are set should be on a valid Fluid Error that would have been returned above,\n\t// but we can't prove it with the types, so adding this defensive measure.\n\tif (typeof error === \"object\" && error !== null) {\n\t\tconst maybeHasRetry: Partial<Record<\"canRetry\" | \"retryAfterSeconds\", unknown>> = error;\n\t\tlet retryProps: Partial<Record<\"canRetry\" | \"retryAfterSeconds\", unknown>> | undefined;\n\t\tif (\"canRetry\" in error) {\n\t\t\tretryProps ??= {};\n\t\t\tretryProps.canRetry = maybeHasRetry.canRetry;\n\t\t}\n\t\tif (\"retryAfterSeconds\" in error) {\n\t\t\tretryProps ??= {};\n\t\t\tretryProps.retryAfterSeconds = maybeHasRetry.retryAfterSeconds;\n\t\t}\n\t\tif (retryProps !== undefined) {\n\t\t\tObject.assign(fluidError, retryProps);\n\t\t}\n\t}\n\n\tif (typeof error !== \"object\") {\n\t\t// This is only interesting for non-objects\n\t\tfluidError.addTelemetryProperties({ typeofError: typeof error });\n\t}\n\n\tconst errorTelemetryProps = LoggingError.typeCheck(error)\n\t\t? error.getTelemetryProperties()\n\t\t: {\n\t\t\t\tuntrustedOrigin: 1, // This will let us filter errors that did not originate from our own codebase\n\t\t\t\t// FUTURE: Once 2.0 becomes LTS, switch to this more explicit property name\n\t\t\t\t// Consider using a string to distinguish cases like \"dependency\" v. \"callback\"\n\t\t\t\t// errorRunningExternalCode: 1,\n\t\t\t};\n\n\tfluidError.addTelemetryProperties({\n\t\t...errorTelemetryProps,\n\t\t...annotations.props,\n\t});\n\n\treturn fluidError;\n}\n\nlet stackPopulatedOnCreation: boolean | undefined;\n\n/**\n * The purpose of this function is to provide ability to capture stack context quickly.\n * Accessing new Error().stack is slow, and the slowest part is accessing stack property itself.\n * There are scenarios where we generate error with stack, but error is handled in most cases and\n * stack property is not accessed.\n * For such cases it's better to not read stack property right away, but rather delay it until / if it's needed\n * Some browsers will populate stack right away, others require throwing Error, so we do auto-detection on the fly.\n * @param stackTraceLimit - stack trace limit for an error\n * @returns Error object that has stack populated.\n *\n * @internal\n */\nexport function generateErrorWithStack(stackTraceLimit?: number): Error {\n\tconst ErrorConfig = Error as unknown as { stackTraceLimit: number };\n\tconst originalStackTraceLimit = ErrorConfig.stackTraceLimit;\n\tif (stackTraceLimit !== undefined) {\n\t\tErrorConfig.stackTraceLimit = stackTraceLimit;\n\t}\n\tconst err = new Error(\"<<generated stack>>\");\n\n\tif (stackPopulatedOnCreation === undefined) {\n\t\tstackPopulatedOnCreation = err.stack !== undefined;\n\t}\n\n\tif (stackPopulatedOnCreation) {\n\t\tErrorConfig.stackTraceLimit = originalStackTraceLimit;\n\t\treturn err;\n\t}\n\n\ttry {\n\t\tthrow err;\n\t} catch (error) {\n\t\tErrorConfig.stackTraceLimit = originalStackTraceLimit;\n\t\treturn error as Error;\n\t}\n}\n\n/**\n * Generate a stack at this callsite as if an error were thrown from here.\n * @param stackTraceLimit - stack trace limit for an error\n * @returns the callstack (does not throw)\n *\n * @internal\n */\nexport function generateStack(stackTraceLimit?: number): string | undefined {\n\treturn generateErrorWithStack(stackTraceLimit).stack;\n}\n\n/**\n * Create a new error using newErrorFn, wrapping and caused by the given unknown error.\n * Copies the inner error's stack, errorInstanceId and telemetry props over to the new error if present\n * @param innerError - An error from untrusted/unknown origins\n * @param newErrorFn - callback that will create a new error given the original error's message\n * @returns A new error object \"wrapping\" the given error\n *\n * @internal\n */\nexport function wrapError<T extends LoggingError>(\n\tinnerError: unknown,\n\tnewErrorFn: (message: string) => T,\n): T {\n\tconst { message, stack } = extractLogSafeErrorProperties(\n\t\tinnerError,\n\t\tfalse /* sanitizeStack */,\n\t);\n\n\tconst newError = newErrorFn(message);\n\n\tnewError.cause = innerError;\n\n\tif (stack !== undefined) {\n\t\toverwriteStack(newError, stack);\n\t}\n\n\t// Mark external errors with untrustedOrigin flag\n\tif (isExternalError(innerError)) {\n\t\tnewError.addTelemetryProperties({\n\t\t\tuntrustedOrigin: 1,\n\t\t\t// FUTURE: Once 2.0 becomes LTS, switch to this more explicit property name\n\t\t\t// Consider using a string to distinguish cases like \"dependency\" v. \"callback\"\n\t\t\t// errorRunningExternalCode: 1,\n\t\t});\n\t}\n\n\t// Reuse errorInstanceId\n\tif (hasErrorInstanceId(innerError)) {\n\t\tnewError.overwriteErrorInstanceId(innerError.errorInstanceId);\n\n\t\t// For \"back-compat\" in the logs\n\t\tnewError.addTelemetryProperties({ innerErrorInstanceId: innerError.errorInstanceId });\n\t}\n\n\t// Lastly, copy over all other telemetry properties. Note these will not overwrite existing properties\n\t// This will include the untrustedOrigin/errorRunningExternalCode info if the inner error itself was created from an external error\n\tif (isILoggingError(innerError)) {\n\t\tnewError.addTelemetryProperties(innerError.getTelemetryProperties());\n\t}\n\n\treturn newError;\n}\n\n/**\n * The same as wrapError, but also logs the innerError, including the wrapping error's instance ID.\n *\n * @typeParam T - The kind of wrapper error to create.\n *\n * @internal\n */\nexport function wrapErrorAndLog<T extends LoggingError>(\n\tinnerError: unknown,\n\tnewErrorFn: (message: string) => T,\n\tlogger: ITelemetryLoggerExt,\n): T {\n\tconst newError = wrapError(innerError, newErrorFn);\n\n\t// This will match innerError.errorInstanceId if present (see wrapError)\n\tconst errorInstanceId = newError.errorInstanceId;\n\n\t// For \"back-compat\" in the logs\n\tconst wrappedByErrorInstanceId = errorInstanceId;\n\n\tlogger.sendTelemetryEvent(\n\t\t{\n\t\t\teventName: \"WrapError\",\n\t\t\terrorInstanceId,\n\t\t\twrappedByErrorInstanceId,\n\t\t},\n\t\tinnerError,\n\t);\n\n\treturn newError;\n}\n\n/**\n * Attempts to overwrite the error's stack\n *\n * There have been reports of certain JS environments where overwriting stack will throw.\n * If that happens, this adds the given stack as the telemetry property \"stack2\"\n *\n * @internal\n */\nexport function overwriteStack(error: IFluidErrorBase | LoggingError, stack: string): void {\n\ttry {\n\t\tObject.assign(error, { stack });\n\t} catch {\n\t\terror.addTelemetryProperties({ stack2: stack });\n\t}\n}\n\n/**\n * True for any error object that is an (optionally normalized) external error\n * False for any error we created and raised within the FF codebase via LoggingError base class,\n * or wrapped in a well-known error type\n *\n * @internal\n */\nexport function isExternalError(error: unknown): boolean {\n\t// LoggingErrors are an internal FF error type. However, an external error can be converted\n\t// into a LoggingError if it is normalized. In this case we must use the untrustedOrigin/errorRunningExternalCode flag to\n\t// determine whether the original error was in fact external.\n\tif (LoggingError.typeCheck(error)) {\n\t\tif ((error as NormalizedLoggingError).errorType === NORMALIZED_ERROR_TYPE) {\n\t\t\tconst props = error.getTelemetryProperties();\n\t\t\t// NOTE: errorRunningExternalCode is not currently used - once this \"read\" code reaches LTS,\n\t\t\t// we can switch to writing this more explicit property\n\t\t\treturn props.untrustedOrigin === 1 || Boolean(props.errorRunningExternalCode);\n\t\t}\n\t\treturn false;\n\t}\n\treturn true;\n}\n\n/**\n * Type guard to identify if a particular telemetry property appears to be a\n * {@link @fluidframework/core-interfaces#Tagged} telemetry property.\n *\n * @internal\n */\nexport function isTaggedTelemetryPropertyValue(\n\tx: Tagged<TelemetryEventPropertyTypeExt> | TelemetryEventPropertyTypeExt,\n): x is Tagged<TelemetryEventPropertyTypeExt> {\n\treturn typeof (x as Partial<Tagged<unknown>>)?.tag === \"string\";\n}\n\n// TODO: Use `unknown` instead (API breaking change)\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/**\n * Borrowed from\n * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cyclic_object_value#examples}\n * Avoids runtime errors with circular references.\n * Not ideal, as will cut values that are not necessarily circular references.\n * Could be improved by implementing Node's util.inspect() for browser (minus all the coloring code)\n *\n * @internal\n */\nexport const getCircularReplacer = (): ((key: string, value: unknown) => any) => {\n\tconst seen = new WeakSet();\n\treturn (key: string, value: unknown): any => {\n\t\tif (typeof value === \"object\" && value !== null) {\n\t\t\tif (seen.has(value)) {\n\t\t\t\treturn \"<removed/circular>\";\n\t\t\t}\n\t\t\tseen.add(value);\n\t\t}\n\t\treturn value;\n\t};\n};\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\n/**\n * Base class for \"trusted\" errors we create, whose properties can generally be logged to telemetry safely.\n * All properties set on the object, or passed in (via the constructor or addTelemetryProperties),\n * will be logged in accordance with their tag, if present.\n *\n * PLEASE take care to avoid setting sensitive data on this object without proper tagging!\n *\n * @internal\n */\nexport class LoggingError\n\textends Error\n\timplements ILoggingError, Omit<IFluidErrorBase, \"errorType\">\n{\n\tpublic cause?: unknown;\n\n\tprivate _errorInstanceId = uuid();\n\tpublic get errorInstanceId(): string {\n\t\treturn this._errorInstanceId;\n\t}\n\tpublic overwriteErrorInstanceId(id: string): void {\n\t\tthis._errorInstanceId = id;\n\t}\n\n\t/**\n\t * Create a new LoggingError\n\t * @param message - Error message to use for Error base class\n\t * @param props - telemetry props to include on the error for when it's logged\n\t * @param omitPropsFromLogging - properties by name to omit from telemetry props\n\t */\n\tpublic constructor(\n\t\tmessage: string,\n\t\tprops?: ITelemetryBaseProperties,\n\t\tprivate readonly omitPropsFromLogging: Set<string> = new Set(),\n\t) {\n\t\tsuper(message);\n\n\t\t// Don't log this list itself, or the private _errorInstanceId\n\t\tomitPropsFromLogging.add(\"omitPropsFromLogging\");\n\t\tomitPropsFromLogging.add(\"_errorInstanceId\");\n\t\t// Nor log the unknown cause property, which could be anything.\n\t\t// Core elements of \"cause\" are already promoted by wrapError.\n\t\tomitPropsFromLogging.add(\"cause\");\n\n\t\tif (props) {\n\t\t\tthis.addTelemetryProperties(props);\n\t\t}\n\t}\n\n\t/**\n\t * Determines if a given object is an instance of a LoggingError\n\t * @param object - any object\n\t * @returns true if the object is an instance of a LoggingError, false if not.\n\t */\n\tpublic static typeCheck(object: unknown): object is LoggingError {\n\t\tif (typeof object === \"object\" && object !== null) {\n\t\t\treturn (\n\t\t\t\ttypeof (object as LoggingError).addTelemetryProperties === \"function\" &&\n\t\t\t\ttypeof (object as LoggingError).getTelemetryProperties === \"function\" &&\n\t\t\t\ttypeof (object as LoggingError).errorInstanceId === \"string\"\n\t\t\t);\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Add additional properties to be logged\n\t */\n\tpublic addTelemetryProperties(props: ITelemetryPropertiesExt): void {\n\t\tcopyProps(this, props);\n\t}\n\n\t/**\n\t * Get all properties fit to be logged to telemetry for this error\n\t */\n\tpublic getTelemetryProperties(): ITelemetryBaseProperties {\n\t\t// Only pick properties fit for telemetry out of all of this object's enumerable properties.\n\t\tconst telemetryProps: ITelemetryBaseProperties = {};\n\t\tfor (const key of Object.keys(this)) {\n\t\t\tif (this.omitPropsFromLogging.has(key)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst val = this[key] as\n\t\t\t\t| TelemetryEventPropertyTypeExt\n\t\t\t\t| Tagged<TelemetryEventPropertyTypeExt>;\n\n\t\t\t// Ensure only valid props get logged, since props of logging error could be in any shape\n\t\t\ttelemetryProps[key] = convertToBasePropertyType(val);\n\t\t}\n\t\t// Ensure a few extra props always exist\n\t\treturn {\n\t\t\t...telemetryProps,\n\t\t\tstack: this.stack,\n\t\t\tmessage: this.message,\n\t\t\terrorInstanceId: this._errorInstanceId,\n\t\t};\n\t}\n}\n\n/**\n * The Error class used when normalizing an external error\n *\n * @internal\n */\nexport const NORMALIZED_ERROR_TYPE = \"genericError\";\n\n/**\n * Subclass of LoggingError returned by normalizeError\n *\n * @internal\n */\nclass NormalizedLoggingError extends LoggingError {\n\t// errorType \"genericError\" is used as a default value throughout the code.\n\t// Note that this matches ContainerErrorTypes/DriverErrorTypes' genericError\n\tpublic readonly errorType = NORMALIZED_ERROR_TYPE;\n\n\tpublic constructor(errorProps: Pick<IFluidErrorBase, \"message\" | \"stack\">) {\n\t\tsuper(errorProps.message);\n\n\t\tif (errorProps.stack !== undefined) {\n\t\t\toverwriteStack(this, errorProps.stack);\n\t\t}\n\t}\n}\n"]}
|
package/dist/fluidErrorBase.d.ts
CHANGED
|
@@ -52,6 +52,19 @@ export interface IFluidErrorBase extends Error {
|
|
|
52
52
|
* or correlating an error with an inner error that caused it, in case of error wrapping.
|
|
53
53
|
*/
|
|
54
54
|
readonly errorInstanceId: string;
|
|
55
|
+
/**
|
|
56
|
+
* When present, inner error that caused this error.
|
|
57
|
+
*
|
|
58
|
+
* @remarks
|
|
59
|
+
* 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.
|
|
60
|
+
*
|
|
61
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause
|
|
62
|
+
*
|
|
63
|
+
* @privateRemarks
|
|
64
|
+
* The "cause" field is added in ES2022. Using it even without that built-in support, is still helpful.
|
|
65
|
+
* TODO: remove this declaration (use `Error.cause` property) when targeting ES2022 lib or later.
|
|
66
|
+
*/
|
|
67
|
+
cause?: unknown;
|
|
55
68
|
/**
|
|
56
69
|
* Get the telemetry properties stashed on this error for logging.
|
|
57
70
|
*/
|
|
@@ -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;AAEhF,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;;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"}
|
|
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;AAEhF,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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fluidErrorBase.js","sourceRoot":"","sources":["../src/fluidErrorBase.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;
|
|
1
|
+
{"version":3,"file":"fluidErrorBase.js","sourceRoot":"","sources":["../src/fluidErrorBase.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAoFH,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","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\";\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"]}
|
package/lib/errorLogging.d.ts
CHANGED
|
@@ -126,6 +126,7 @@ export declare const getCircularReplacer: () => ((key: string, value: unknown) =
|
|
|
126
126
|
*/
|
|
127
127
|
export declare class LoggingError extends Error implements ILoggingError, Omit<IFluidErrorBase, "errorType"> {
|
|
128
128
|
private readonly omitPropsFromLogging;
|
|
129
|
+
cause?: unknown;
|
|
129
130
|
private _errorInstanceId;
|
|
130
131
|
get errorInstanceId(): string;
|
|
131
132
|
overwriteErrorInstanceId(id: string): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errorLogging.d.ts","sourceRoot":"","sources":["../src/errorLogging.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,EAAE,MAAM,iCAAiC,CAAC;AACxF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0CAA0C,CAAC;AAG9E,OAAO,EAAE,KAAK,eAAe,EAAoC,MAAM,qBAAqB,CAAC;AAE7F,OAAO,KAAK,EACX,mBAAmB,EACnB,uBAAuB,EACvB,6BAA6B,EAC7B,MAAM,qBAAqB,CAAC;AAS7B;;;;GAIG;AACH,wBAAgB,6BAA6B,CAC5C,KAAK,EAAE,OAAO,EACd,aAAa,EAAE,OAAO,GACpB;IACF,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B,CAoCA;AAED;;;;GAIG;AACH,eAAO,MAAM,eAAe,MAAO,OAAO,uBACkC,CAAC;AAgB7E;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACtC;;OAEG;IACH,KAAK,CAAC,EAAE,wBAAwB,CAAC;CACjC;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC7B,KAAK,EAAE,OAAO,EACd,WAAW,GAAE,sBAA2B,GACtC,eAAe,CAqDjB;AAID;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,KAAK,CAuBtE;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE1E;AAED;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,YAAY,EAC/C,UAAU,EAAE,OAAO,EACnB,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,CAAC,GAChC,CAAC,
|
|
1
|
+
{"version":3,"file":"errorLogging.d.ts","sourceRoot":"","sources":["../src/errorLogging.ts"],"names":[],"mappings":"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"}
|
package/lib/errorLogging.js
CHANGED
|
@@ -175,6 +175,7 @@ export function generateStack(stackTraceLimit) {
|
|
|
175
175
|
export function wrapError(innerError, newErrorFn) {
|
|
176
176
|
const { message, stack } = extractLogSafeErrorProperties(innerError, false /* sanitizeStack */);
|
|
177
177
|
const newError = newErrorFn(message);
|
|
178
|
+
newError.cause = innerError;
|
|
178
179
|
if (stack !== undefined) {
|
|
179
180
|
overwriteStack(newError, stack);
|
|
180
181
|
}
|
|
@@ -320,6 +321,9 @@ export class LoggingError extends Error {
|
|
|
320
321
|
// Don't log this list itself, or the private _errorInstanceId
|
|
321
322
|
omitPropsFromLogging.add("omitPropsFromLogging");
|
|
322
323
|
omitPropsFromLogging.add("_errorInstanceId");
|
|
324
|
+
// Nor log the unknown cause property, which could be anything.
|
|
325
|
+
// Core elements of "cause" are already promoted by wrapError.
|
|
326
|
+
omitPropsFromLogging.add("cause");
|
|
323
327
|
if (props) {
|
|
324
328
|
this.addTelemetryProperties(props);
|
|
325
329
|
}
|
package/lib/errorLogging.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errorLogging.js","sourceRoot":"","sources":["../src/errorLogging.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 { ITelemetryBaseProperties, Tagged } from \"@fluidframework/core-interfaces\";\nimport type { ILoggingError } from \"@fluidframework/core-interfaces/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport { type IFluidErrorBase, hasErrorInstanceId, isFluidError } from \"./fluidErrorBase.js\";\nimport { convertToBasePropertyType } from \"./logger.js\";\nimport type {\n\tITelemetryLoggerExt,\n\tITelemetryPropertiesExt,\n\tTelemetryEventPropertyTypeExt,\n} from \"./telemetryTypes.js\";\n\n/**\n * Determines if the provided value is an object but neither null nor an array.\n */\nconst isRegularObject = (value: unknown): boolean => {\n\treturn value !== null && !Array.isArray(value) && typeof value === \"object\";\n};\n\n/**\n * Inspect the given error for common \"safe\" props and return them.\n *\n * @internal\n */\nexport function extractLogSafeErrorProperties(\n\terror: unknown,\n\tsanitizeStack: boolean,\n): {\n\tmessage: string;\n\terrorType?: string | undefined;\n\tstack?: string | undefined;\n} {\n\tconst removeMessageFromStack = (stack: string, errorName?: string): string => {\n\t\tif (!sanitizeStack) {\n\t\t\treturn stack;\n\t\t}\n\t\tconst stackFrames = stack.split(\"\\n\");\n\t\tstackFrames.shift(); // Remove \"[ErrorName]: [ErrorMessage]\"\n\t\tif (errorName !== undefined) {\n\t\t\tstackFrames.unshift(errorName); // Add \"[ErrorName]\"\n\t\t}\n\t\treturn stackFrames.join(\"\\n\");\n\t};\n\n\tconst message =\n\t\ttypeof (error as Partial<Error>)?.message === \"string\"\n\t\t\t? (error as Error).message\n\t\t\t: String(error);\n\n\tconst safeProps: { message: string; errorType?: string; stack?: string } = {\n\t\tmessage,\n\t};\n\n\tif (isRegularObject(error)) {\n\t\tconst { errorType, stack, name } = error as Partial<IFluidErrorBase>;\n\n\t\tif (typeof errorType === \"string\") {\n\t\t\tsafeProps.errorType = errorType;\n\t\t}\n\n\t\tif (typeof stack === \"string\") {\n\t\t\tconst errorName = typeof name === \"string\" ? name : undefined;\n\t\t\tsafeProps.stack = removeMessageFromStack(stack, errorName);\n\t\t}\n\t}\n\n\treturn safeProps;\n}\n\n/**\n * Type-guard for {@link @fluidframework/core-interfaces#ILoggingError}.\n *\n * @internal\n */\nexport const isILoggingError = (x: unknown): x is ILoggingError =>\n\ttypeof (x as Partial<ILoggingError>)?.getTelemetryProperties === \"function\";\n\n/**\n * Copy props from source onto target, but do not overwrite an existing prop that matches\n */\nfunction copyProps(\n\ttarget: ITelemetryPropertiesExt | LoggingError,\n\tsource: ITelemetryPropertiesExt,\n): void {\n\tfor (const [key, value] of Object.entries(source)) {\n\t\tif (target[key] === undefined) {\n\t\t\ttarget[key] = value;\n\t\t}\n\t}\n}\n\n/**\n * Metadata to annotate an error object when annotating or normalizing it\n *\n * @internal\n */\nexport interface IFluidErrorAnnotations {\n\t/**\n\t * Telemetry props to log with the error\n\t */\n\tprops?: ITelemetryBaseProperties;\n}\n\n/**\n * Normalize the given error yielding a valid Fluid Error\n * @returns A valid Fluid Error with any provided annotations applied\n * @param error - The error to normalize\n * @param annotations - Annotations to apply to the normalized error\n *\n * @internal\n */\nexport function normalizeError(\n\terror: unknown,\n\tannotations: IFluidErrorAnnotations = {},\n): IFluidErrorBase {\n\tif (isFluidError(error)) {\n\t\t// We can simply add the telemetry props to the error and return it\n\t\terror.addTelemetryProperties(annotations.props ?? {});\n\t\treturn error;\n\t}\n\n\t// We have to construct a new Fluid Error, copying safe properties over\n\tconst { message, stack } = extractLogSafeErrorProperties(error, false /* sanitizeStack */);\n\tconst fluidError: IFluidErrorBase = new NormalizedLoggingError({\n\t\tmessage,\n\t\tstack,\n\t});\n\n\t// We need to preserve these properties which are used in a non-typesafe way throughout driver code (see #8743)\n\t// Anywhere they are set should be on a valid Fluid Error that would have been returned above,\n\t// but we can't prove it with the types, so adding this defensive measure.\n\tif (typeof error === \"object\" && error !== null) {\n\t\tconst maybeHasRetry: Partial<Record<\"canRetry\" | \"retryAfterSeconds\", unknown>> = error;\n\t\tlet retryProps: Partial<Record<\"canRetry\" | \"retryAfterSeconds\", unknown>> | undefined;\n\t\tif (\"canRetry\" in error) {\n\t\t\tretryProps ??= {};\n\t\t\tretryProps.canRetry = maybeHasRetry.canRetry;\n\t\t}\n\t\tif (\"retryAfterSeconds\" in error) {\n\t\t\tretryProps ??= {};\n\t\t\tretryProps.retryAfterSeconds = maybeHasRetry.retryAfterSeconds;\n\t\t}\n\t\tif (retryProps !== undefined) {\n\t\t\tObject.assign(fluidError, retryProps);\n\t\t}\n\t}\n\n\tif (typeof error !== \"object\") {\n\t\t// This is only interesting for non-objects\n\t\tfluidError.addTelemetryProperties({ typeofError: typeof error });\n\t}\n\n\tconst errorTelemetryProps = LoggingError.typeCheck(error)\n\t\t? error.getTelemetryProperties()\n\t\t: {\n\t\t\t\tuntrustedOrigin: 1, // This will let us filter errors that did not originate from our own codebase\n\t\t\t\t// FUTURE: Once 2.0 becomes LTS, switch to this more explicit property name\n\t\t\t\t// Consider using a string to distinguish cases like \"dependency\" v. \"callback\"\n\t\t\t\t// errorRunningExternalCode: 1,\n\t\t\t};\n\n\tfluidError.addTelemetryProperties({\n\t\t...errorTelemetryProps,\n\t\t...annotations.props,\n\t});\n\n\treturn fluidError;\n}\n\nlet stackPopulatedOnCreation: boolean | undefined;\n\n/**\n * The purpose of this function is to provide ability to capture stack context quickly.\n * Accessing new Error().stack is slow, and the slowest part is accessing stack property itself.\n * There are scenarios where we generate error with stack, but error is handled in most cases and\n * stack property is not accessed.\n * For such cases it's better to not read stack property right away, but rather delay it until / if it's needed\n * Some browsers will populate stack right away, others require throwing Error, so we do auto-detection on the fly.\n * @param stackTraceLimit - stack trace limit for an error\n * @returns Error object that has stack populated.\n *\n * @internal\n */\nexport function generateErrorWithStack(stackTraceLimit?: number): Error {\n\tconst ErrorConfig = Error as unknown as { stackTraceLimit: number };\n\tconst originalStackTraceLimit = ErrorConfig.stackTraceLimit;\n\tif (stackTraceLimit !== undefined) {\n\t\tErrorConfig.stackTraceLimit = stackTraceLimit;\n\t}\n\tconst err = new Error(\"<<generated stack>>\");\n\n\tif (stackPopulatedOnCreation === undefined) {\n\t\tstackPopulatedOnCreation = err.stack !== undefined;\n\t}\n\n\tif (stackPopulatedOnCreation) {\n\t\tErrorConfig.stackTraceLimit = originalStackTraceLimit;\n\t\treturn err;\n\t}\n\n\ttry {\n\t\tthrow err;\n\t} catch (error) {\n\t\tErrorConfig.stackTraceLimit = originalStackTraceLimit;\n\t\treturn error as Error;\n\t}\n}\n\n/**\n * Generate a stack at this callsite as if an error were thrown from here.\n * @param stackTraceLimit - stack trace limit for an error\n * @returns the callstack (does not throw)\n *\n * @internal\n */\nexport function generateStack(stackTraceLimit?: number): string | undefined {\n\treturn generateErrorWithStack(stackTraceLimit).stack;\n}\n\n/**\n * Create a new error using newErrorFn, wrapping and caused by the given unknown error.\n * Copies the inner error's stack, errorInstanceId and telemetry props over to the new error if present\n * @param innerError - An error from untrusted/unknown origins\n * @param newErrorFn - callback that will create a new error given the original error's message\n * @returns A new error object \"wrapping\" the given error\n *\n * @internal\n */\nexport function wrapError<T extends LoggingError>(\n\tinnerError: unknown,\n\tnewErrorFn: (message: string) => T,\n): T {\n\tconst { message, stack } = extractLogSafeErrorProperties(\n\t\tinnerError,\n\t\tfalse /* sanitizeStack */,\n\t);\n\n\tconst newError = newErrorFn(message);\n\n\tif (stack !== undefined) {\n\t\toverwriteStack(newError, stack);\n\t}\n\n\t// Mark external errors with untrustedOrigin flag\n\tif (isExternalError(innerError)) {\n\t\tnewError.addTelemetryProperties({\n\t\t\tuntrustedOrigin: 1,\n\t\t\t// FUTURE: Once 2.0 becomes LTS, switch to this more explicit property name\n\t\t\t// Consider using a string to distinguish cases like \"dependency\" v. \"callback\"\n\t\t\t// errorRunningExternalCode: 1,\n\t\t});\n\t}\n\n\t// Reuse errorInstanceId\n\tif (hasErrorInstanceId(innerError)) {\n\t\tnewError.overwriteErrorInstanceId(innerError.errorInstanceId);\n\n\t\t// For \"back-compat\" in the logs\n\t\tnewError.addTelemetryProperties({ innerErrorInstanceId: innerError.errorInstanceId });\n\t}\n\n\t// Lastly, copy over all other telemetry properties. Note these will not overwrite existing properties\n\t// This will include the untrustedOrigin/errorRunningExternalCode info if the inner error itself was created from an external error\n\tif (isILoggingError(innerError)) {\n\t\tnewError.addTelemetryProperties(innerError.getTelemetryProperties());\n\t}\n\n\treturn newError;\n}\n\n/**\n * The same as wrapError, but also logs the innerError, including the wrapping error's instance ID.\n *\n * @typeParam T - The kind of wrapper error to create.\n *\n * @internal\n */\nexport function wrapErrorAndLog<T extends LoggingError>(\n\tinnerError: unknown,\n\tnewErrorFn: (message: string) => T,\n\tlogger: ITelemetryLoggerExt,\n): T {\n\tconst newError = wrapError(innerError, newErrorFn);\n\n\t// This will match innerError.errorInstanceId if present (see wrapError)\n\tconst errorInstanceId = newError.errorInstanceId;\n\n\t// For \"back-compat\" in the logs\n\tconst wrappedByErrorInstanceId = errorInstanceId;\n\n\tlogger.sendTelemetryEvent(\n\t\t{\n\t\t\teventName: \"WrapError\",\n\t\t\terrorInstanceId,\n\t\t\twrappedByErrorInstanceId,\n\t\t},\n\t\tinnerError,\n\t);\n\n\treturn newError;\n}\n\n/**\n * Attempts to overwrite the error's stack\n *\n * There have been reports of certain JS environments where overwriting stack will throw.\n * If that happens, this adds the given stack as the telemetry property \"stack2\"\n *\n * @internal\n */\nexport function overwriteStack(error: IFluidErrorBase | LoggingError, stack: string): void {\n\ttry {\n\t\tObject.assign(error, { stack });\n\t} catch {\n\t\terror.addTelemetryProperties({ stack2: stack });\n\t}\n}\n\n/**\n * True for any error object that is an (optionally normalized) external error\n * False for any error we created and raised within the FF codebase via LoggingError base class,\n * or wrapped in a well-known error type\n *\n * @internal\n */\nexport function isExternalError(error: unknown): boolean {\n\t// LoggingErrors are an internal FF error type. However, an external error can be converted\n\t// into a LoggingError if it is normalized. In this case we must use the untrustedOrigin/errorRunningExternalCode flag to\n\t// determine whether the original error was in fact external.\n\tif (LoggingError.typeCheck(error)) {\n\t\tif ((error as NormalizedLoggingError).errorType === NORMALIZED_ERROR_TYPE) {\n\t\t\tconst props = error.getTelemetryProperties();\n\t\t\t// NOTE: errorRunningExternalCode is not currently used - once this \"read\" code reaches LTS,\n\t\t\t// we can switch to writing this more explicit property\n\t\t\treturn props.untrustedOrigin === 1 || Boolean(props.errorRunningExternalCode);\n\t\t}\n\t\treturn false;\n\t}\n\treturn true;\n}\n\n/**\n * Type guard to identify if a particular telemetry property appears to be a\n * {@link @fluidframework/core-interfaces#Tagged} telemetry property.\n *\n * @internal\n */\nexport function isTaggedTelemetryPropertyValue(\n\tx: Tagged<TelemetryEventPropertyTypeExt> | TelemetryEventPropertyTypeExt,\n): x is Tagged<TelemetryEventPropertyTypeExt> {\n\treturn typeof (x as Partial<Tagged<unknown>>)?.tag === \"string\";\n}\n\n// TODO: Use `unknown` instead (API breaking change)\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/**\n * Borrowed from\n * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cyclic_object_value#examples}\n * Avoids runtime errors with circular references.\n * Not ideal, as will cut values that are not necessarily circular references.\n * Could be improved by implementing Node's util.inspect() for browser (minus all the coloring code)\n *\n * @internal\n */\nexport const getCircularReplacer = (): ((key: string, value: unknown) => any) => {\n\tconst seen = new WeakSet();\n\treturn (key: string, value: unknown): any => {\n\t\tif (typeof value === \"object\" && value !== null) {\n\t\t\tif (seen.has(value)) {\n\t\t\t\treturn \"<removed/circular>\";\n\t\t\t}\n\t\t\tseen.add(value);\n\t\t}\n\t\treturn value;\n\t};\n};\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\n/**\n * Base class for \"trusted\" errors we create, whose properties can generally be logged to telemetry safely.\n * All properties set on the object, or passed in (via the constructor or addTelemetryProperties),\n * will be logged in accordance with their tag, if present.\n *\n * PLEASE take care to avoid setting sensitive data on this object without proper tagging!\n *\n * @internal\n */\nexport class LoggingError\n\textends Error\n\timplements ILoggingError, Omit<IFluidErrorBase, \"errorType\">\n{\n\tprivate _errorInstanceId = uuid();\n\tpublic get errorInstanceId(): string {\n\t\treturn this._errorInstanceId;\n\t}\n\tpublic overwriteErrorInstanceId(id: string): void {\n\t\tthis._errorInstanceId = id;\n\t}\n\n\t/**\n\t * Create a new LoggingError\n\t * @param message - Error message to use for Error base class\n\t * @param props - telemetry props to include on the error for when it's logged\n\t * @param omitPropsFromLogging - properties by name to omit from telemetry props\n\t */\n\tpublic constructor(\n\t\tmessage: string,\n\t\tprops?: ITelemetryBaseProperties,\n\t\tprivate readonly omitPropsFromLogging: Set<string> = new Set(),\n\t) {\n\t\tsuper(message);\n\n\t\t// Don't log this list itself, or the private _errorInstanceId\n\t\tomitPropsFromLogging.add(\"omitPropsFromLogging\");\n\t\tomitPropsFromLogging.add(\"_errorInstanceId\");\n\n\t\tif (props) {\n\t\t\tthis.addTelemetryProperties(props);\n\t\t}\n\t}\n\n\t/**\n\t * Determines if a given object is an instance of a LoggingError\n\t * @param object - any object\n\t * @returns true if the object is an instance of a LoggingError, false if not.\n\t */\n\tpublic static typeCheck(object: unknown): object is LoggingError {\n\t\tif (typeof object === \"object\" && object !== null) {\n\t\t\treturn (\n\t\t\t\ttypeof (object as LoggingError).addTelemetryProperties === \"function\" &&\n\t\t\t\ttypeof (object as LoggingError).getTelemetryProperties === \"function\" &&\n\t\t\t\ttypeof (object as LoggingError).errorInstanceId === \"string\"\n\t\t\t);\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Add additional properties to be logged\n\t */\n\tpublic addTelemetryProperties(props: ITelemetryPropertiesExt): void {\n\t\tcopyProps(this, props);\n\t}\n\n\t/**\n\t * Get all properties fit to be logged to telemetry for this error\n\t */\n\tpublic getTelemetryProperties(): ITelemetryBaseProperties {\n\t\t// Only pick properties fit for telemetry out of all of this object's enumerable properties.\n\t\tconst telemetryProps: ITelemetryBaseProperties = {};\n\t\tfor (const key of Object.keys(this)) {\n\t\t\tif (this.omitPropsFromLogging.has(key)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst val = this[key] as\n\t\t\t\t| TelemetryEventPropertyTypeExt\n\t\t\t\t| Tagged<TelemetryEventPropertyTypeExt>;\n\n\t\t\t// Ensure only valid props get logged, since props of logging error could be in any shape\n\t\t\ttelemetryProps[key] = convertToBasePropertyType(val);\n\t\t}\n\t\t// Ensure a few extra props always exist\n\t\treturn {\n\t\t\t...telemetryProps,\n\t\t\tstack: this.stack,\n\t\t\tmessage: this.message,\n\t\t\terrorInstanceId: this._errorInstanceId,\n\t\t};\n\t}\n}\n\n/**\n * The Error class used when normalizing an external error\n *\n * @internal\n */\nexport const NORMALIZED_ERROR_TYPE = \"genericError\";\n\n/**\n * Subclass of LoggingError returned by normalizeError\n *\n * @internal\n */\nclass NormalizedLoggingError extends LoggingError {\n\t// errorType \"genericError\" is used as a default value throughout the code.\n\t// Note that this matches ContainerErrorTypes/DriverErrorTypes' genericError\n\tpublic readonly errorType = NORMALIZED_ERROR_TYPE;\n\n\tpublic constructor(errorProps: Pick<IFluidErrorBase, \"message\" | \"stack\">) {\n\t\tsuper(errorProps.message);\n\n\t\tif (errorProps.stack !== undefined) {\n\t\t\toverwriteStack(this, errorProps.stack);\n\t\t}\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"errorLogging.js","sourceRoot":"","sources":["../src/errorLogging.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 { ITelemetryBaseProperties, Tagged } from \"@fluidframework/core-interfaces\";\nimport type { ILoggingError } from \"@fluidframework/core-interfaces/internal\";\nimport { v4 as uuid } from \"uuid\";\n\nimport { type IFluidErrorBase, hasErrorInstanceId, isFluidError } from \"./fluidErrorBase.js\";\nimport { convertToBasePropertyType } from \"./logger.js\";\nimport type {\n\tITelemetryLoggerExt,\n\tITelemetryPropertiesExt,\n\tTelemetryEventPropertyTypeExt,\n} from \"./telemetryTypes.js\";\n\n/**\n * Determines if the provided value is an object but neither null nor an array.\n */\nconst isRegularObject = (value: unknown): boolean => {\n\treturn value !== null && !Array.isArray(value) && typeof value === \"object\";\n};\n\n/**\n * Inspect the given error for common \"safe\" props and return them.\n *\n * @internal\n */\nexport function extractLogSafeErrorProperties(\n\terror: unknown,\n\tsanitizeStack: boolean,\n): {\n\tmessage: string;\n\terrorType?: string | undefined;\n\tstack?: string | undefined;\n} {\n\tconst removeMessageFromStack = (stack: string, errorName?: string): string => {\n\t\tif (!sanitizeStack) {\n\t\t\treturn stack;\n\t\t}\n\t\tconst stackFrames = stack.split(\"\\n\");\n\t\tstackFrames.shift(); // Remove \"[ErrorName]: [ErrorMessage]\"\n\t\tif (errorName !== undefined) {\n\t\t\tstackFrames.unshift(errorName); // Add \"[ErrorName]\"\n\t\t}\n\t\treturn stackFrames.join(\"\\n\");\n\t};\n\n\tconst message =\n\t\ttypeof (error as Partial<Error>)?.message === \"string\"\n\t\t\t? (error as Error).message\n\t\t\t: String(error);\n\n\tconst safeProps: { message: string; errorType?: string; stack?: string } = {\n\t\tmessage,\n\t};\n\n\tif (isRegularObject(error)) {\n\t\tconst { errorType, stack, name } = error as Partial<IFluidErrorBase>;\n\n\t\tif (typeof errorType === \"string\") {\n\t\t\tsafeProps.errorType = errorType;\n\t\t}\n\n\t\tif (typeof stack === \"string\") {\n\t\t\tconst errorName = typeof name === \"string\" ? name : undefined;\n\t\t\tsafeProps.stack = removeMessageFromStack(stack, errorName);\n\t\t}\n\t}\n\n\treturn safeProps;\n}\n\n/**\n * Type-guard for {@link @fluidframework/core-interfaces#ILoggingError}.\n *\n * @internal\n */\nexport const isILoggingError = (x: unknown): x is ILoggingError =>\n\ttypeof (x as Partial<ILoggingError>)?.getTelemetryProperties === \"function\";\n\n/**\n * Copy props from source onto target, but do not overwrite an existing prop that matches\n */\nfunction copyProps(\n\ttarget: ITelemetryPropertiesExt | LoggingError,\n\tsource: ITelemetryPropertiesExt,\n): void {\n\tfor (const [key, value] of Object.entries(source)) {\n\t\tif (target[key] === undefined) {\n\t\t\ttarget[key] = value;\n\t\t}\n\t}\n}\n\n/**\n * Metadata to annotate an error object when annotating or normalizing it\n *\n * @internal\n */\nexport interface IFluidErrorAnnotations {\n\t/**\n\t * Telemetry props to log with the error\n\t */\n\tprops?: ITelemetryBaseProperties;\n}\n\n/**\n * Normalize the given error yielding a valid Fluid Error\n * @returns A valid Fluid Error with any provided annotations applied\n * @param error - The error to normalize\n * @param annotations - Annotations to apply to the normalized error\n *\n * @internal\n */\nexport function normalizeError(\n\terror: unknown,\n\tannotations: IFluidErrorAnnotations = {},\n): IFluidErrorBase {\n\tif (isFluidError(error)) {\n\t\t// We can simply add the telemetry props to the error and return it\n\t\terror.addTelemetryProperties(annotations.props ?? {});\n\t\treturn error;\n\t}\n\n\t// We have to construct a new Fluid Error, copying safe properties over\n\tconst { message, stack } = extractLogSafeErrorProperties(error, false /* sanitizeStack */);\n\tconst fluidError: IFluidErrorBase = new NormalizedLoggingError({\n\t\tmessage,\n\t\tstack,\n\t});\n\n\t// We need to preserve these properties which are used in a non-typesafe way throughout driver code (see #8743)\n\t// Anywhere they are set should be on a valid Fluid Error that would have been returned above,\n\t// but we can't prove it with the types, so adding this defensive measure.\n\tif (typeof error === \"object\" && error !== null) {\n\t\tconst maybeHasRetry: Partial<Record<\"canRetry\" | \"retryAfterSeconds\", unknown>> = error;\n\t\tlet retryProps: Partial<Record<\"canRetry\" | \"retryAfterSeconds\", unknown>> | undefined;\n\t\tif (\"canRetry\" in error) {\n\t\t\tretryProps ??= {};\n\t\t\tretryProps.canRetry = maybeHasRetry.canRetry;\n\t\t}\n\t\tif (\"retryAfterSeconds\" in error) {\n\t\t\tretryProps ??= {};\n\t\t\tretryProps.retryAfterSeconds = maybeHasRetry.retryAfterSeconds;\n\t\t}\n\t\tif (retryProps !== undefined) {\n\t\t\tObject.assign(fluidError, retryProps);\n\t\t}\n\t}\n\n\tif (typeof error !== \"object\") {\n\t\t// This is only interesting for non-objects\n\t\tfluidError.addTelemetryProperties({ typeofError: typeof error });\n\t}\n\n\tconst errorTelemetryProps = LoggingError.typeCheck(error)\n\t\t? error.getTelemetryProperties()\n\t\t: {\n\t\t\t\tuntrustedOrigin: 1, // This will let us filter errors that did not originate from our own codebase\n\t\t\t\t// FUTURE: Once 2.0 becomes LTS, switch to this more explicit property name\n\t\t\t\t// Consider using a string to distinguish cases like \"dependency\" v. \"callback\"\n\t\t\t\t// errorRunningExternalCode: 1,\n\t\t\t};\n\n\tfluidError.addTelemetryProperties({\n\t\t...errorTelemetryProps,\n\t\t...annotations.props,\n\t});\n\n\treturn fluidError;\n}\n\nlet stackPopulatedOnCreation: boolean | undefined;\n\n/**\n * The purpose of this function is to provide ability to capture stack context quickly.\n * Accessing new Error().stack is slow, and the slowest part is accessing stack property itself.\n * There are scenarios where we generate error with stack, but error is handled in most cases and\n * stack property is not accessed.\n * For such cases it's better to not read stack property right away, but rather delay it until / if it's needed\n * Some browsers will populate stack right away, others require throwing Error, so we do auto-detection on the fly.\n * @param stackTraceLimit - stack trace limit for an error\n * @returns Error object that has stack populated.\n *\n * @internal\n */\nexport function generateErrorWithStack(stackTraceLimit?: number): Error {\n\tconst ErrorConfig = Error as unknown as { stackTraceLimit: number };\n\tconst originalStackTraceLimit = ErrorConfig.stackTraceLimit;\n\tif (stackTraceLimit !== undefined) {\n\t\tErrorConfig.stackTraceLimit = stackTraceLimit;\n\t}\n\tconst err = new Error(\"<<generated stack>>\");\n\n\tif (stackPopulatedOnCreation === undefined) {\n\t\tstackPopulatedOnCreation = err.stack !== undefined;\n\t}\n\n\tif (stackPopulatedOnCreation) {\n\t\tErrorConfig.stackTraceLimit = originalStackTraceLimit;\n\t\treturn err;\n\t}\n\n\ttry {\n\t\tthrow err;\n\t} catch (error) {\n\t\tErrorConfig.stackTraceLimit = originalStackTraceLimit;\n\t\treturn error as Error;\n\t}\n}\n\n/**\n * Generate a stack at this callsite as if an error were thrown from here.\n * @param stackTraceLimit - stack trace limit for an error\n * @returns the callstack (does not throw)\n *\n * @internal\n */\nexport function generateStack(stackTraceLimit?: number): string | undefined {\n\treturn generateErrorWithStack(stackTraceLimit).stack;\n}\n\n/**\n * Create a new error using newErrorFn, wrapping and caused by the given unknown error.\n * Copies the inner error's stack, errorInstanceId and telemetry props over to the new error if present\n * @param innerError - An error from untrusted/unknown origins\n * @param newErrorFn - callback that will create a new error given the original error's message\n * @returns A new error object \"wrapping\" the given error\n *\n * @internal\n */\nexport function wrapError<T extends LoggingError>(\n\tinnerError: unknown,\n\tnewErrorFn: (message: string) => T,\n): T {\n\tconst { message, stack } = extractLogSafeErrorProperties(\n\t\tinnerError,\n\t\tfalse /* sanitizeStack */,\n\t);\n\n\tconst newError = newErrorFn(message);\n\n\tnewError.cause = innerError;\n\n\tif (stack !== undefined) {\n\t\toverwriteStack(newError, stack);\n\t}\n\n\t// Mark external errors with untrustedOrigin flag\n\tif (isExternalError(innerError)) {\n\t\tnewError.addTelemetryProperties({\n\t\t\tuntrustedOrigin: 1,\n\t\t\t// FUTURE: Once 2.0 becomes LTS, switch to this more explicit property name\n\t\t\t// Consider using a string to distinguish cases like \"dependency\" v. \"callback\"\n\t\t\t// errorRunningExternalCode: 1,\n\t\t});\n\t}\n\n\t// Reuse errorInstanceId\n\tif (hasErrorInstanceId(innerError)) {\n\t\tnewError.overwriteErrorInstanceId(innerError.errorInstanceId);\n\n\t\t// For \"back-compat\" in the logs\n\t\tnewError.addTelemetryProperties({ innerErrorInstanceId: innerError.errorInstanceId });\n\t}\n\n\t// Lastly, copy over all other telemetry properties. Note these will not overwrite existing properties\n\t// This will include the untrustedOrigin/errorRunningExternalCode info if the inner error itself was created from an external error\n\tif (isILoggingError(innerError)) {\n\t\tnewError.addTelemetryProperties(innerError.getTelemetryProperties());\n\t}\n\n\treturn newError;\n}\n\n/**\n * The same as wrapError, but also logs the innerError, including the wrapping error's instance ID.\n *\n * @typeParam T - The kind of wrapper error to create.\n *\n * @internal\n */\nexport function wrapErrorAndLog<T extends LoggingError>(\n\tinnerError: unknown,\n\tnewErrorFn: (message: string) => T,\n\tlogger: ITelemetryLoggerExt,\n): T {\n\tconst newError = wrapError(innerError, newErrorFn);\n\n\t// This will match innerError.errorInstanceId if present (see wrapError)\n\tconst errorInstanceId = newError.errorInstanceId;\n\n\t// For \"back-compat\" in the logs\n\tconst wrappedByErrorInstanceId = errorInstanceId;\n\n\tlogger.sendTelemetryEvent(\n\t\t{\n\t\t\teventName: \"WrapError\",\n\t\t\terrorInstanceId,\n\t\t\twrappedByErrorInstanceId,\n\t\t},\n\t\tinnerError,\n\t);\n\n\treturn newError;\n}\n\n/**\n * Attempts to overwrite the error's stack\n *\n * There have been reports of certain JS environments where overwriting stack will throw.\n * If that happens, this adds the given stack as the telemetry property \"stack2\"\n *\n * @internal\n */\nexport function overwriteStack(error: IFluidErrorBase | LoggingError, stack: string): void {\n\ttry {\n\t\tObject.assign(error, { stack });\n\t} catch {\n\t\terror.addTelemetryProperties({ stack2: stack });\n\t}\n}\n\n/**\n * True for any error object that is an (optionally normalized) external error\n * False for any error we created and raised within the FF codebase via LoggingError base class,\n * or wrapped in a well-known error type\n *\n * @internal\n */\nexport function isExternalError(error: unknown): boolean {\n\t// LoggingErrors are an internal FF error type. However, an external error can be converted\n\t// into a LoggingError if it is normalized. In this case we must use the untrustedOrigin/errorRunningExternalCode flag to\n\t// determine whether the original error was in fact external.\n\tif (LoggingError.typeCheck(error)) {\n\t\tif ((error as NormalizedLoggingError).errorType === NORMALIZED_ERROR_TYPE) {\n\t\t\tconst props = error.getTelemetryProperties();\n\t\t\t// NOTE: errorRunningExternalCode is not currently used - once this \"read\" code reaches LTS,\n\t\t\t// we can switch to writing this more explicit property\n\t\t\treturn props.untrustedOrigin === 1 || Boolean(props.errorRunningExternalCode);\n\t\t}\n\t\treturn false;\n\t}\n\treturn true;\n}\n\n/**\n * Type guard to identify if a particular telemetry property appears to be a\n * {@link @fluidframework/core-interfaces#Tagged} telemetry property.\n *\n * @internal\n */\nexport function isTaggedTelemetryPropertyValue(\n\tx: Tagged<TelemetryEventPropertyTypeExt> | TelemetryEventPropertyTypeExt,\n): x is Tagged<TelemetryEventPropertyTypeExt> {\n\treturn typeof (x as Partial<Tagged<unknown>>)?.tag === \"string\";\n}\n\n// TODO: Use `unknown` instead (API breaking change)\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/**\n * Borrowed from\n * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Cyclic_object_value#examples}\n * Avoids runtime errors with circular references.\n * Not ideal, as will cut values that are not necessarily circular references.\n * Could be improved by implementing Node's util.inspect() for browser (minus all the coloring code)\n *\n * @internal\n */\nexport const getCircularReplacer = (): ((key: string, value: unknown) => any) => {\n\tconst seen = new WeakSet();\n\treturn (key: string, value: unknown): any => {\n\t\tif (typeof value === \"object\" && value !== null) {\n\t\t\tif (seen.has(value)) {\n\t\t\t\treturn \"<removed/circular>\";\n\t\t\t}\n\t\t\tseen.add(value);\n\t\t}\n\t\treturn value;\n\t};\n};\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\n/**\n * Base class for \"trusted\" errors we create, whose properties can generally be logged to telemetry safely.\n * All properties set on the object, or passed in (via the constructor or addTelemetryProperties),\n * will be logged in accordance with their tag, if present.\n *\n * PLEASE take care to avoid setting sensitive data on this object without proper tagging!\n *\n * @internal\n */\nexport class LoggingError\n\textends Error\n\timplements ILoggingError, Omit<IFluidErrorBase, \"errorType\">\n{\n\tpublic cause?: unknown;\n\n\tprivate _errorInstanceId = uuid();\n\tpublic get errorInstanceId(): string {\n\t\treturn this._errorInstanceId;\n\t}\n\tpublic overwriteErrorInstanceId(id: string): void {\n\t\tthis._errorInstanceId = id;\n\t}\n\n\t/**\n\t * Create a new LoggingError\n\t * @param message - Error message to use for Error base class\n\t * @param props - telemetry props to include on the error for when it's logged\n\t * @param omitPropsFromLogging - properties by name to omit from telemetry props\n\t */\n\tpublic constructor(\n\t\tmessage: string,\n\t\tprops?: ITelemetryBaseProperties,\n\t\tprivate readonly omitPropsFromLogging: Set<string> = new Set(),\n\t) {\n\t\tsuper(message);\n\n\t\t// Don't log this list itself, or the private _errorInstanceId\n\t\tomitPropsFromLogging.add(\"omitPropsFromLogging\");\n\t\tomitPropsFromLogging.add(\"_errorInstanceId\");\n\t\t// Nor log the unknown cause property, which could be anything.\n\t\t// Core elements of \"cause\" are already promoted by wrapError.\n\t\tomitPropsFromLogging.add(\"cause\");\n\n\t\tif (props) {\n\t\t\tthis.addTelemetryProperties(props);\n\t\t}\n\t}\n\n\t/**\n\t * Determines if a given object is an instance of a LoggingError\n\t * @param object - any object\n\t * @returns true if the object is an instance of a LoggingError, false if not.\n\t */\n\tpublic static typeCheck(object: unknown): object is LoggingError {\n\t\tif (typeof object === \"object\" && object !== null) {\n\t\t\treturn (\n\t\t\t\ttypeof (object as LoggingError).addTelemetryProperties === \"function\" &&\n\t\t\t\ttypeof (object as LoggingError).getTelemetryProperties === \"function\" &&\n\t\t\t\ttypeof (object as LoggingError).errorInstanceId === \"string\"\n\t\t\t);\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Add additional properties to be logged\n\t */\n\tpublic addTelemetryProperties(props: ITelemetryPropertiesExt): void {\n\t\tcopyProps(this, props);\n\t}\n\n\t/**\n\t * Get all properties fit to be logged to telemetry for this error\n\t */\n\tpublic getTelemetryProperties(): ITelemetryBaseProperties {\n\t\t// Only pick properties fit for telemetry out of all of this object's enumerable properties.\n\t\tconst telemetryProps: ITelemetryBaseProperties = {};\n\t\tfor (const key of Object.keys(this)) {\n\t\t\tif (this.omitPropsFromLogging.has(key)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tconst val = this[key] as\n\t\t\t\t| TelemetryEventPropertyTypeExt\n\t\t\t\t| Tagged<TelemetryEventPropertyTypeExt>;\n\n\t\t\t// Ensure only valid props get logged, since props of logging error could be in any shape\n\t\t\ttelemetryProps[key] = convertToBasePropertyType(val);\n\t\t}\n\t\t// Ensure a few extra props always exist\n\t\treturn {\n\t\t\t...telemetryProps,\n\t\t\tstack: this.stack,\n\t\t\tmessage: this.message,\n\t\t\terrorInstanceId: this._errorInstanceId,\n\t\t};\n\t}\n}\n\n/**\n * The Error class used when normalizing an external error\n *\n * @internal\n */\nexport const NORMALIZED_ERROR_TYPE = \"genericError\";\n\n/**\n * Subclass of LoggingError returned by normalizeError\n *\n * @internal\n */\nclass NormalizedLoggingError extends LoggingError {\n\t// errorType \"genericError\" is used as a default value throughout the code.\n\t// Note that this matches ContainerErrorTypes/DriverErrorTypes' genericError\n\tpublic readonly errorType = NORMALIZED_ERROR_TYPE;\n\n\tpublic constructor(errorProps: Pick<IFluidErrorBase, \"message\" | \"stack\">) {\n\t\tsuper(errorProps.message);\n\n\t\tif (errorProps.stack !== undefined) {\n\t\t\toverwriteStack(this, errorProps.stack);\n\t\t}\n\t}\n}\n"]}
|
package/lib/fluidErrorBase.d.ts
CHANGED
|
@@ -52,6 +52,19 @@ export interface IFluidErrorBase extends Error {
|
|
|
52
52
|
* or correlating an error with an inner error that caused it, in case of error wrapping.
|
|
53
53
|
*/
|
|
54
54
|
readonly errorInstanceId: string;
|
|
55
|
+
/**
|
|
56
|
+
* When present, inner error that caused this error.
|
|
57
|
+
*
|
|
58
|
+
* @remarks
|
|
59
|
+
* 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.
|
|
60
|
+
*
|
|
61
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause
|
|
62
|
+
*
|
|
63
|
+
* @privateRemarks
|
|
64
|
+
* The "cause" field is added in ES2022. Using it even without that built-in support, is still helpful.
|
|
65
|
+
* TODO: remove this declaration (use `Error.cause` property) when targeting ES2022 lib or later.
|
|
66
|
+
*/
|
|
67
|
+
cause?: unknown;
|
|
55
68
|
/**
|
|
56
69
|
* Get the telemetry properties stashed on this error for logging.
|
|
57
70
|
*/
|
|
@@ -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;AAEhF,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;;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"}
|
|
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;AAEhF,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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fluidErrorBase.js","sourceRoot":"","sources":["../src/fluidErrorBase.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"fluidErrorBase.js","sourceRoot":"","sources":["../src/fluidErrorBase.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAoFH,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","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\";\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"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluidframework/telemetry-utils",
|
|
3
|
-
"version": "2.61.0
|
|
3
|
+
"version": "2.61.0",
|
|
4
4
|
"description": "Collection of telemetry relates utilities for Fluid",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -69,17 +69,17 @@
|
|
|
69
69
|
"temp-directory": "nyc/.nyc_output"
|
|
70
70
|
},
|
|
71
71
|
"dependencies": {
|
|
72
|
-
"@fluid-internal/client-utils": "2.61.0
|
|
73
|
-
"@fluidframework/core-interfaces": "2.61.0
|
|
74
|
-
"@fluidframework/core-utils": "2.61.0
|
|
75
|
-
"@fluidframework/driver-definitions": "2.61.0
|
|
72
|
+
"@fluid-internal/client-utils": "~2.61.0",
|
|
73
|
+
"@fluidframework/core-interfaces": "~2.61.0",
|
|
74
|
+
"@fluidframework/core-utils": "~2.61.0",
|
|
75
|
+
"@fluidframework/driver-definitions": "~2.61.0",
|
|
76
76
|
"debug": "^4.3.4",
|
|
77
77
|
"uuid": "^11.1.0"
|
|
78
78
|
},
|
|
79
79
|
"devDependencies": {
|
|
80
80
|
"@arethetypeswrong/cli": "^0.17.1",
|
|
81
81
|
"@biomejs/biome": "~1.9.3",
|
|
82
|
-
"@fluid-internal/mocha-test-setup": "2.61.0
|
|
82
|
+
"@fluid-internal/mocha-test-setup": "~2.61.0",
|
|
83
83
|
"@fluid-tools/build-cli": "^0.58.3",
|
|
84
84
|
"@fluidframework/build-common": "^2.0.3",
|
|
85
85
|
"@fluidframework/build-tools": "^0.58.3",
|
package/src/errorLogging.ts
CHANGED
|
@@ -242,6 +242,8 @@ export function wrapError<T extends LoggingError>(
|
|
|
242
242
|
|
|
243
243
|
const newError = newErrorFn(message);
|
|
244
244
|
|
|
245
|
+
newError.cause = innerError;
|
|
246
|
+
|
|
245
247
|
if (stack !== undefined) {
|
|
246
248
|
overwriteStack(newError, stack);
|
|
247
249
|
}
|
|
@@ -394,6 +396,8 @@ export class LoggingError
|
|
|
394
396
|
extends Error
|
|
395
397
|
implements ILoggingError, Omit<IFluidErrorBase, "errorType">
|
|
396
398
|
{
|
|
399
|
+
public cause?: unknown;
|
|
400
|
+
|
|
397
401
|
private _errorInstanceId = uuid();
|
|
398
402
|
public get errorInstanceId(): string {
|
|
399
403
|
return this._errorInstanceId;
|
|
@@ -418,6 +422,9 @@ export class LoggingError
|
|
|
418
422
|
// Don't log this list itself, or the private _errorInstanceId
|
|
419
423
|
omitPropsFromLogging.add("omitPropsFromLogging");
|
|
420
424
|
omitPropsFromLogging.add("_errorInstanceId");
|
|
425
|
+
// Nor log the unknown cause property, which could be anything.
|
|
426
|
+
// Core elements of "cause" are already promoted by wrapError.
|
|
427
|
+
omitPropsFromLogging.add("cause");
|
|
421
428
|
|
|
422
429
|
if (props) {
|
|
423
430
|
this.addTelemetryProperties(props);
|
package/src/fluidErrorBase.ts
CHANGED
|
@@ -60,6 +60,20 @@ export interface IFluidErrorBase extends Error {
|
|
|
60
60
|
*/
|
|
61
61
|
readonly errorInstanceId: string;
|
|
62
62
|
|
|
63
|
+
/**
|
|
64
|
+
* When present, inner error that caused this error.
|
|
65
|
+
*
|
|
66
|
+
* @remarks
|
|
67
|
+
* 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.
|
|
68
|
+
*
|
|
69
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause
|
|
70
|
+
*
|
|
71
|
+
* @privateRemarks
|
|
72
|
+
* The "cause" field is added in ES2022. Using it even without that built-in support, is still helpful.
|
|
73
|
+
* TODO: remove this declaration (use `Error.cause` property) when targeting ES2022 lib or later.
|
|
74
|
+
*/
|
|
75
|
+
cause?: unknown;
|
|
76
|
+
|
|
63
77
|
/**
|
|
64
78
|
* Get the telemetry properties stashed on this error for logging.
|
|
65
79
|
*/
|