@fluidframework/telemetry-utils 2.0.0-dev-rc.2.0.0.245554 → 2.0.0-dev-rc.3.0.0.250606
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +4 -0
- package/dist/config.js.map +1 -1
- package/dist/error.d.ts +1 -1
- package/dist/error.d.ts.map +1 -1
- package/dist/error.js.map +1 -1
- package/dist/errorLogging.d.ts +1 -1
- package/dist/errorLogging.d.ts.map +1 -1
- package/dist/errorLogging.js.map +1 -1
- package/dist/eventEmitterWithErrorHandling.d.ts +1 -1
- package/dist/eventEmitterWithErrorHandling.d.ts.map +1 -1
- package/dist/eventEmitterWithErrorHandling.js +2 -2
- package/dist/eventEmitterWithErrorHandling.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/logger.d.ts +2 -2
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +1 -1
- package/dist/logger.js.map +1 -1
- package/dist/mockLogger.d.ts.map +1 -1
- package/dist/mockLogger.js.map +1 -1
- package/dist/sampledTelemetryHelper.d.ts +2 -2
- package/dist/sampledTelemetryHelper.d.ts.map +1 -1
- package/dist/sampledTelemetryHelper.js.map +1 -1
- package/dist/utils.d.ts +4 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +4 -0
- package/dist/utils.js.map +1 -1
- package/lib/config.d.ts +1 -1
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js +4 -0
- package/lib/config.js.map +1 -1
- package/lib/error.d.ts +1 -1
- package/lib/error.d.ts.map +1 -1
- package/lib/error.js.map +1 -1
- package/lib/errorLogging.d.ts +1 -1
- package/lib/errorLogging.d.ts.map +1 -1
- package/lib/errorLogging.js.map +1 -1
- package/lib/eventEmitterWithErrorHandling.d.ts +1 -1
- package/lib/eventEmitterWithErrorHandling.d.ts.map +1 -1
- package/lib/eventEmitterWithErrorHandling.js.map +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js.map +1 -1
- package/lib/logger.d.ts +2 -2
- package/lib/logger.d.ts.map +1 -1
- package/lib/logger.js +2 -2
- package/lib/logger.js.map +1 -1
- package/lib/mockLogger.d.ts.map +1 -1
- package/lib/mockLogger.js.map +1 -1
- package/lib/sampledTelemetryHelper.d.ts +2 -2
- package/lib/sampledTelemetryHelper.d.ts.map +1 -1
- package/lib/sampledTelemetryHelper.js.map +1 -1
- package/lib/test/errorLogging.spec.js +2 -2
- package/lib/test/errorLogging.spec.js.map +1 -1
- package/lib/test/errorTypeLoggingTest.spec.js +2 -2
- package/lib/test/errorTypeLoggingTest.spec.js.map +1 -1
- package/lib/test/performanceEvent.spec.js +1 -1
- package/lib/test/performanceEvent.spec.js.map +1 -1
- package/lib/test/sampledTelemetryHelper.spec.js.map +1 -1
- package/lib/test/telemetryLogger.spec.js.map +1 -1
- package/lib/test/thresholdCounter.spec.js.map +1 -1
- package/lib/test/utils.spec.js +2 -2
- package/lib/test/utils.spec.js.map +1 -1
- package/lib/utils.d.ts +4 -0
- package/lib/utils.d.ts.map +1 -1
- package/lib/utils.js +4 -0
- package/lib/utils.js.map +1 -1
- package/package.json +13 -10
- package/src/config.ts +3 -2
- package/src/error.ts +1 -1
- package/src/errorLogging.ts +3 -3
- package/src/eventEmitterWithErrorHandling.ts +2 -1
- package/src/index.ts +1 -0
- package/src/logger.ts +6 -6
- package/src/mockLogger.ts +1 -1
- package/src/sampledTelemetryHelper.ts +2 -2
- package/src/utils.ts +1 -0
package/lib/mockLogger.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mockLogger.js","sourceRoot":"","sources":["../src/mockLogger.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tITelemetryBaseEvent,\n\tITelemetryBaseLogger,\n\tLogLevel,\n} from \"@fluidframework/core-interfaces\";\nimport { assert } from \"@fluidframework/core-utils\";\nimport { ITelemetryLoggerExt, ITelemetryPropertiesExt } from \"./telemetryTypes.js\";\nimport { createChildLogger } from \"./logger.js\";\n\n/**\n * The MockLogger records events sent to it, and then can walk back over those events\n * searching for a set of expected events to match against the logged events.\n *\n * @internal\n */\nexport class MockLogger implements ITelemetryBaseLogger {\n\tevents: ITelemetryBaseEvent[] = [];\n\n\tconstructor(public readonly minLogLevel?: LogLevel) {}\n\n\tclear(): void {\n\t\tthis.events = [];\n\t}\n\n\ttoTelemetryLogger(): ITelemetryLoggerExt {\n\t\treturn createChildLogger({ logger: this });\n\t}\n\n\tsend(event: ITelemetryBaseEvent): void {\n\t\tthis.events.push(event);\n\t}\n\n\t/**\n\t * Search events logged since the last time matchEvents was called, looking for the given expected\n\t * events in order.\n\t * @param expectedEvents - events in order that are expected to appear in the recorded log.\n\t * @param inlineDetailsProp - true if the \"details\" property in the actual event should be extracted and inlined.\n\t * These event objects may be subsets of the logged events.\n\t * Note: category is omitted from the type because it's usually uninteresting and tedious to type.\n\t */\n\tmatchEvents(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tinlineDetailsProp: boolean = false,\n\t): boolean {\n\t\tconst matchedExpectedEventCount = this.getMatchedEventsCount(\n\t\t\texpectedEvents,\n\t\t\tinlineDetailsProp,\n\t\t);\n\t\t// How many expected events were left over? Hopefully none.\n\t\tconst unmatchedExpectedEventCount = expectedEvents.length - matchedExpectedEventCount;\n\t\treturn unmatchedExpectedEventCount === 0;\n\t}\n\n\t/**\n\t * Asserts that matchEvents is true, and prints the actual/expected output if not.\n\t */\n\tassertMatch(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t): void {\n\t\tconst actualEvents = this.events;\n\t\tif (!this.matchEvents(expectedEvents, inlineDetailsProp)) {\n\t\t\tthrow new Error(`${message}\nexpected:\n${JSON.stringify(expectedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\t/**\n\t * Search events logged since the last time matchEvents was called, looking for any of the given\n\t * expected events.\n\t * @param expectedEvents - events that are expected to appear in the recorded log.\n\t * @param inlineDetailsProp - true if the \"details\" property in the actual event should be extracted and inlined.\n\t * These event objects may be subsets of the logged events.\n\t * Note: category is omitted from the type because it's usually uninteresting and tedious to type.\n\t * @returns if any of the expected events is found.\n\t */\n\tmatchAnyEvent(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tinlineDetailsProp: boolean = false,\n\t): boolean {\n\t\tconst matchedExpectedEventCount = this.getMatchedEventsCount(\n\t\t\texpectedEvents,\n\t\t\tinlineDetailsProp,\n\t\t);\n\t\treturn matchedExpectedEventCount > 0;\n\t}\n\n\t/**\n\t * Asserts that matchAnyEvent is true, and prints the actual/expected output if not.\n\t */\n\tassertMatchAny(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t): void {\n\t\tconst actualEvents = this.events;\n\t\tif (!this.matchAnyEvent(expectedEvents, inlineDetailsProp)) {\n\t\t\tthrow new Error(`${message}\nexpected:\n${JSON.stringify(expectedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\t/**\n\t * Search events logged since the last time matchEvents was called, looking only for the given expected\n\t * events in order.\n\t * @param expectedEvents - events in order that are expected to be the only events in the recorded log.\n\t * @param inlineDetailsProp - true if the \"details\" property in the actual event should be extracted and inlined.\n\t * These event objects may be subsets of the logged events.\n\t * Note: category is omitted from the type because it's usually uninteresting and tedious to type.\n\t */\n\tmatchEventStrict(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tinlineDetailsProp: boolean = false,\n\t): boolean {\n\t\treturn (\n\t\t\texpectedEvents.length === this.events.length &&\n\t\t\tthis.matchEvents(expectedEvents, inlineDetailsProp)\n\t\t);\n\t}\n\n\t/**\n\t * Asserts that matchEvents is true, and prints the actual/expected output if not\n\t */\n\tassertMatchStrict(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t): void {\n\t\tconst actualEvents = this.events;\n\t\tif (!this.matchEventStrict(expectedEvents, inlineDetailsProp)) {\n\t\t\tthrow new Error(`${message}\nexpected:\n${JSON.stringify(expectedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\t/**\n\t * Asserts that matchAnyEvent is false for the given events, and prints the actual/expected output if not\n\t */\n\tassertMatchNone(\n\t\tdisallowedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t): void {\n\t\tconst actualEvents = this.events;\n\t\tif (this.matchAnyEvent(disallowedEvents, inlineDetailsProp)) {\n\t\t\tthrow new Error(`${message}\ndisallowed events:\n${JSON.stringify(disallowedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\tprivate getMatchedEventsCount(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tinlineDetailsProp: boolean,\n\t): number {\n\t\tlet iExpectedEvent = 0;\n\t\tfor (const event of this.events) {\n\t\t\tif (\n\t\t\t\tiExpectedEvent < expectedEvents.length &&\n\t\t\t\tMockLogger.eventsMatch(event, expectedEvents[iExpectedEvent], inlineDetailsProp)\n\t\t\t) {\n\t\t\t\t// We found the next expected event; increment\n\t\t\t\t++iExpectedEvent;\n\t\t\t}\n\t\t}\n\n\t\t// Remove the events so far; next call will just compare subsequent events from here\n\t\tthis.events = [];\n\n\t\t// Return the count of matched events.\n\t\treturn iExpectedEvent;\n\t}\n\n\t/**\n\t * Ensure the expected event is a strict subset of the actual event\n\t */\n\tprivate static eventsMatch(\n\t\tactual: ITelemetryBaseEvent,\n\t\texpected: Omit<ITelemetryBaseEvent, \"category\">,\n\t\tinlineDetailsProp: boolean,\n\t): boolean {\n\t\tconst { details, ...actualForMatching } = actual;\n\t\t// \"details\" is used in a lot of telemetry logs to group a bunch of properties together and stringify them.\n\t\t// Some of the properties in the expected event may be inside \"details\". So, if inlineDetailsProp is true,\n\t\t// extract the properties from \"details\" in the actual event and inline them in the actual event.\n\t\tif (inlineDetailsProp && details !== undefined) {\n\t\t\tassert(\n\t\t\t\ttypeof details === \"string\",\n\t\t\t\t// eslint-disable-next-line unicorn/numeric-separators-style\n\t\t\t\t0x6c9 /* Details should a JSON stringified string if inlineDetailsProp is true */,\n\t\t\t);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\t\tconst detailsExpanded = JSON.parse(details);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\treturn matchObjects({ ...actualForMatching, ...detailsExpanded }, expected);\n\t\t}\n\t\treturn matchObjects(actual, expected);\n\t}\n}\n\nfunction matchObjects(actual: ITelemetryPropertiesExt, expected: ITelemetryPropertiesExt): boolean {\n\tfor (const [expectedKey, expectedValue] of Object.entries(expected)) {\n\t\tconst actualValue = actual[expectedKey];\n\t\tif (\n\t\t\t!Array.isArray(expectedValue) &&\n\t\t\texpectedValue !== null &&\n\t\t\ttypeof expectedValue === \"object\"\n\t\t) {\n\t\t\tif (\n\t\t\t\tArray.isArray(actualValue) ||\n\t\t\t\tactualValue === null ||\n\t\t\t\ttypeof actualValue !== \"object\" ||\n\t\t\t\t!matchObjects(\n\t\t\t\t\tactualValue as ITelemetryPropertiesExt,\n\t\t\t\t\texpectedValue as ITelemetryPropertiesExt,\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} else if (JSON.stringify(actualValue) !== JSON.stringify(expectedValue)) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mockLogger.js","sourceRoot":"","sources":["../src/mockLogger.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGhD;;;;;GAKG;AACH,MAAM,OAAO,UAAU;IAGtB,YAA4B,WAAsB;QAAtB,gBAAW,GAAX,WAAW,CAAW;QAFlD,WAAM,GAA0B,EAAE,CAAC;IAEkB,CAAC;IAEtD,KAAK;QACJ,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;IAClB,CAAC;IAED,iBAAiB;QAChB,OAAO,iBAAiB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5C,CAAC;IAED,IAAI,CAAC,KAA0B;QAC9B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;IAED;;;;;;;OAOG;IACH,WAAW,CACV,cAAuD,EACvD,oBAA6B,KAAK;QAElC,MAAM,yBAAyB,GAAG,IAAI,CAAC,qBAAqB,CAC3D,cAAc,EACd,iBAAiB,CACjB,CAAC;QACF,2DAA2D;QAC3D,MAAM,2BAA2B,GAAG,cAAc,CAAC,MAAM,GAAG,yBAAyB,CAAC;QACtF,OAAO,2BAA2B,KAAK,CAAC,CAAC;IAC1C,CAAC;IAED;;OAEG;IACH,WAAW,CACV,cAAuD,EACvD,OAAgB,EAChB,oBAA6B,KAAK;QAElC,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC;QACjC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,cAAc,EAAE,iBAAiB,CAAC,EAAE;YACzD,MAAM,IAAI,KAAK,CAAC,GAAG,OAAO;;EAE3B,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC;;;EAG9B,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;SAC/B;IACF,CAAC;IAED;;;;;;;;OAQG;IACH,aAAa,CACZ,cAAuD,EACvD,oBAA6B,KAAK;QAElC,MAAM,yBAAyB,GAAG,IAAI,CAAC,qBAAqB,CAC3D,cAAc,EACd,iBAAiB,CACjB,CAAC;QACF,OAAO,yBAAyB,GAAG,CAAC,CAAC;IACtC,CAAC;IAED;;OAEG;IACH,cAAc,CACb,cAAuD,EACvD,OAAgB,EAChB,oBAA6B,KAAK;QAElC,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC;QACjC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,cAAc,EAAE,iBAAiB,CAAC,EAAE;YAC3D,MAAM,IAAI,KAAK,CAAC,GAAG,OAAO;;EAE3B,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC;;;EAG9B,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;SAC/B;IACF,CAAC;IAED;;;;;;;OAOG;IACH,gBAAgB,CACf,cAAuD,EACvD,oBAA6B,KAAK;QAElC,OAAO,CACN,cAAc,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM,CAAC,MAAM;YAC5C,IAAI,CAAC,WAAW,CAAC,cAAc,EAAE,iBAAiB,CAAC,CACnD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,iBAAiB,CAChB,cAAuD,EACvD,OAAgB,EAChB,oBAA6B,KAAK;QAElC,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC;QACjC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,cAAc,EAAE,iBAAiB,CAAC,EAAE;YAC9D,MAAM,IAAI,KAAK,CAAC,GAAG,OAAO;;EAE3B,IAAI,CAAC,SAAS,CAAC,cAAc,CAAC;;;EAG9B,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;SAC/B;IACF,CAAC;IAED;;OAEG;IACH,eAAe,CACd,gBAAyD,EACzD,OAAgB,EAChB,oBAA6B,KAAK;QAElC,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC;QACjC,IAAI,IAAI,CAAC,aAAa,CAAC,gBAAgB,EAAE,iBAAiB,CAAC,EAAE;YAC5D,MAAM,IAAI,KAAK,CAAC,GAAG,OAAO;;EAE3B,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC;;;EAGhC,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;SAC/B;IACF,CAAC;IAEO,qBAAqB,CAC5B,cAAuD,EACvD,iBAA0B;QAE1B,IAAI,cAAc,GAAG,CAAC,CAAC;QACvB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE;YAChC,IACC,cAAc,GAAG,cAAc,CAAC,MAAM;gBACtC,UAAU,CAAC,WAAW,CAAC,KAAK,EAAE,cAAc,CAAC,cAAc,CAAC,EAAE,iBAAiB,CAAC,EAC/E;gBACD,8CAA8C;gBAC9C,EAAE,cAAc,CAAC;aACjB;SACD;QAED,oFAAoF;QACpF,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC;QAEjB,sCAAsC;QACtC,OAAO,cAAc,CAAC;IACvB,CAAC;IAED;;OAEG;IACK,MAAM,CAAC,WAAW,CACzB,MAA2B,EAC3B,QAA+C,EAC/C,iBAA0B;QAE1B,MAAM,EAAE,OAAO,EAAE,GAAG,iBAAiB,EAAE,GAAG,MAAM,CAAC;QACjD,2GAA2G;QAC3G,0GAA0G;QAC1G,iGAAiG;QACjG,IAAI,iBAAiB,IAAI,OAAO,KAAK,SAAS,EAAE;YAC/C,MAAM,CACL,OAAO,OAAO,KAAK,QAAQ;YAC3B,4DAA4D;YAC5D,KAAK,CAAC,2EAA2E,CACjF,CAAC;YACF,mEAAmE;YACnE,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YAC5C,iEAAiE;YACjE,OAAO,YAAY,CAAC,EAAE,GAAG,iBAAiB,EAAE,GAAG,eAAe,EAAE,EAAE,QAAQ,CAAC,CAAC;SAC5E;QACD,OAAO,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACvC,CAAC;CACD;AAED,SAAS,YAAY,CAAC,MAA+B,EAAE,QAAiC;IACvF,KAAK,MAAM,CAAC,WAAW,EAAE,aAAa,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;QACpE,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;QACxC,IACC,CAAC,KAAK,CAAC,OAAO,CAAC,aAAa,CAAC;YAC7B,aAAa,KAAK,IAAI;YACtB,OAAO,aAAa,KAAK,QAAQ,EAChC;YACD,IACC,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC;gBAC1B,WAAW,KAAK,IAAI;gBACpB,OAAO,WAAW,KAAK,QAAQ;gBAC/B,CAAC,YAAY,CACZ,WAAsC,EACtC,aAAwC,CACxC,EACA;gBACD,OAAO,KAAK,CAAC;aACb;SACD;aAAM,IAAI,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,EAAE;YACzE,OAAO,KAAK,CAAC;SACb;KACD;IACD,OAAO,IAAI,CAAC;AACb,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport {\n\tITelemetryBaseEvent,\n\tITelemetryBaseLogger,\n\tLogLevel,\n} from \"@fluidframework/core-interfaces\";\nimport { assert } from \"@fluidframework/core-utils\";\nimport { createChildLogger } from \"./logger.js\";\nimport { ITelemetryLoggerExt, ITelemetryPropertiesExt } from \"./telemetryTypes.js\";\n\n/**\n * The MockLogger records events sent to it, and then can walk back over those events\n * searching for a set of expected events to match against the logged events.\n *\n * @internal\n */\nexport class MockLogger implements ITelemetryBaseLogger {\n\tevents: ITelemetryBaseEvent[] = [];\n\n\tconstructor(public readonly minLogLevel?: LogLevel) {}\n\n\tclear(): void {\n\t\tthis.events = [];\n\t}\n\n\ttoTelemetryLogger(): ITelemetryLoggerExt {\n\t\treturn createChildLogger({ logger: this });\n\t}\n\n\tsend(event: ITelemetryBaseEvent): void {\n\t\tthis.events.push(event);\n\t}\n\n\t/**\n\t * Search events logged since the last time matchEvents was called, looking for the given expected\n\t * events in order.\n\t * @param expectedEvents - events in order that are expected to appear in the recorded log.\n\t * @param inlineDetailsProp - true if the \"details\" property in the actual event should be extracted and inlined.\n\t * These event objects may be subsets of the logged events.\n\t * Note: category is omitted from the type because it's usually uninteresting and tedious to type.\n\t */\n\tmatchEvents(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tinlineDetailsProp: boolean = false,\n\t): boolean {\n\t\tconst matchedExpectedEventCount = this.getMatchedEventsCount(\n\t\t\texpectedEvents,\n\t\t\tinlineDetailsProp,\n\t\t);\n\t\t// How many expected events were left over? Hopefully none.\n\t\tconst unmatchedExpectedEventCount = expectedEvents.length - matchedExpectedEventCount;\n\t\treturn unmatchedExpectedEventCount === 0;\n\t}\n\n\t/**\n\t * Asserts that matchEvents is true, and prints the actual/expected output if not.\n\t */\n\tassertMatch(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t): void {\n\t\tconst actualEvents = this.events;\n\t\tif (!this.matchEvents(expectedEvents, inlineDetailsProp)) {\n\t\t\tthrow new Error(`${message}\nexpected:\n${JSON.stringify(expectedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\t/**\n\t * Search events logged since the last time matchEvents was called, looking for any of the given\n\t * expected events.\n\t * @param expectedEvents - events that are expected to appear in the recorded log.\n\t * @param inlineDetailsProp - true if the \"details\" property in the actual event should be extracted and inlined.\n\t * These event objects may be subsets of the logged events.\n\t * Note: category is omitted from the type because it's usually uninteresting and tedious to type.\n\t * @returns if any of the expected events is found.\n\t */\n\tmatchAnyEvent(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tinlineDetailsProp: boolean = false,\n\t): boolean {\n\t\tconst matchedExpectedEventCount = this.getMatchedEventsCount(\n\t\t\texpectedEvents,\n\t\t\tinlineDetailsProp,\n\t\t);\n\t\treturn matchedExpectedEventCount > 0;\n\t}\n\n\t/**\n\t * Asserts that matchAnyEvent is true, and prints the actual/expected output if not.\n\t */\n\tassertMatchAny(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t): void {\n\t\tconst actualEvents = this.events;\n\t\tif (!this.matchAnyEvent(expectedEvents, inlineDetailsProp)) {\n\t\t\tthrow new Error(`${message}\nexpected:\n${JSON.stringify(expectedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\t/**\n\t * Search events logged since the last time matchEvents was called, looking only for the given expected\n\t * events in order.\n\t * @param expectedEvents - events in order that are expected to be the only events in the recorded log.\n\t * @param inlineDetailsProp - true if the \"details\" property in the actual event should be extracted and inlined.\n\t * These event objects may be subsets of the logged events.\n\t * Note: category is omitted from the type because it's usually uninteresting and tedious to type.\n\t */\n\tmatchEventStrict(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tinlineDetailsProp: boolean = false,\n\t): boolean {\n\t\treturn (\n\t\t\texpectedEvents.length === this.events.length &&\n\t\t\tthis.matchEvents(expectedEvents, inlineDetailsProp)\n\t\t);\n\t}\n\n\t/**\n\t * Asserts that matchEvents is true, and prints the actual/expected output if not\n\t */\n\tassertMatchStrict(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t): void {\n\t\tconst actualEvents = this.events;\n\t\tif (!this.matchEventStrict(expectedEvents, inlineDetailsProp)) {\n\t\t\tthrow new Error(`${message}\nexpected:\n${JSON.stringify(expectedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\t/**\n\t * Asserts that matchAnyEvent is false for the given events, and prints the actual/expected output if not\n\t */\n\tassertMatchNone(\n\t\tdisallowedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tmessage?: string,\n\t\tinlineDetailsProp: boolean = false,\n\t): void {\n\t\tconst actualEvents = this.events;\n\t\tif (this.matchAnyEvent(disallowedEvents, inlineDetailsProp)) {\n\t\t\tthrow new Error(`${message}\ndisallowed events:\n${JSON.stringify(disallowedEvents)}\n\nactual:\n${JSON.stringify(actualEvents)}`);\n\t\t}\n\t}\n\n\tprivate getMatchedEventsCount(\n\t\texpectedEvents: Omit<ITelemetryBaseEvent, \"category\">[],\n\t\tinlineDetailsProp: boolean,\n\t): number {\n\t\tlet iExpectedEvent = 0;\n\t\tfor (const event of this.events) {\n\t\t\tif (\n\t\t\t\tiExpectedEvent < expectedEvents.length &&\n\t\t\t\tMockLogger.eventsMatch(event, expectedEvents[iExpectedEvent], inlineDetailsProp)\n\t\t\t) {\n\t\t\t\t// We found the next expected event; increment\n\t\t\t\t++iExpectedEvent;\n\t\t\t}\n\t\t}\n\n\t\t// Remove the events so far; next call will just compare subsequent events from here\n\t\tthis.events = [];\n\n\t\t// Return the count of matched events.\n\t\treturn iExpectedEvent;\n\t}\n\n\t/**\n\t * Ensure the expected event is a strict subset of the actual event\n\t */\n\tprivate static eventsMatch(\n\t\tactual: ITelemetryBaseEvent,\n\t\texpected: Omit<ITelemetryBaseEvent, \"category\">,\n\t\tinlineDetailsProp: boolean,\n\t): boolean {\n\t\tconst { details, ...actualForMatching } = actual;\n\t\t// \"details\" is used in a lot of telemetry logs to group a bunch of properties together and stringify them.\n\t\t// Some of the properties in the expected event may be inside \"details\". So, if inlineDetailsProp is true,\n\t\t// extract the properties from \"details\" in the actual event and inline them in the actual event.\n\t\tif (inlineDetailsProp && details !== undefined) {\n\t\t\tassert(\n\t\t\t\ttypeof details === \"string\",\n\t\t\t\t// eslint-disable-next-line unicorn/numeric-separators-style\n\t\t\t\t0x6c9 /* Details should a JSON stringified string if inlineDetailsProp is true */,\n\t\t\t);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n\t\t\tconst detailsExpanded = JSON.parse(details);\n\t\t\t// eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n\t\t\treturn matchObjects({ ...actualForMatching, ...detailsExpanded }, expected);\n\t\t}\n\t\treturn matchObjects(actual, expected);\n\t}\n}\n\nfunction matchObjects(actual: ITelemetryPropertiesExt, expected: ITelemetryPropertiesExt): boolean {\n\tfor (const [expectedKey, expectedValue] of Object.entries(expected)) {\n\t\tconst actualValue = actual[expectedKey];\n\t\tif (\n\t\t\t!Array.isArray(expectedValue) &&\n\t\t\texpectedValue !== null &&\n\t\t\ttypeof expectedValue === \"object\"\n\t\t) {\n\t\t\tif (\n\t\t\t\tArray.isArray(actualValue) ||\n\t\t\t\tactualValue === null ||\n\t\t\t\ttypeof actualValue !== \"object\" ||\n\t\t\t\t!matchObjects(\n\t\t\t\t\tactualValue as ITelemetryPropertiesExt,\n\t\t\t\t\texpectedValue as ITelemetryPropertiesExt,\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} else if (JSON.stringify(actualValue) !== JSON.stringify(expectedValue)) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\n"]}
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
3
|
* Licensed under the MIT License.
|
|
4
4
|
*/
|
|
5
|
-
import type {
|
|
6
|
-
import {
|
|
5
|
+
import type { IDisposable, ITelemetryBaseProperties } from "@fluidframework/core-interfaces";
|
|
6
|
+
import { type ITelemetryGenericEventExt, ITelemetryLoggerExt } from "./telemetryTypes.js";
|
|
7
7
|
/**
|
|
8
8
|
* Helper class that executes a specified code block and writes an
|
|
9
9
|
* {@link @fluidframework/core-interfaces#ITelemetryPerformanceEvent} to a specified logger every time a specified
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sampledTelemetryHelper.d.ts","sourceRoot":"","sources":["../src/sampledTelemetryHelper.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"sampledTelemetryHelper.d.ts","sourceRoot":"","sources":["../src/sampledTelemetryHelper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAC7F,OAAO,EACN,KAAK,yBAAyB,EAC9B,mBAAmB,EAEnB,MAAM,qBAAqB,CAAC;AAoC7B;;;;;;;;;;GAUG;AACH,qBAAa,sBAAuB,YAAW,WAAW;IAwBxD,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,uBAAuB;IACxC,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IA3BrC,QAAQ,EAAE,OAAO,CAAS;IAE1B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAmC;IAEnE;;;;;;;;;;;;;;;;;OAiBG;gBAEe,SAAS,EAAE,yBAAyB,EACpC,MAAM,EAAE,mBAAmB,EAC3B,eAAe,EAAE,MAAM,EACvB,uBAAuB,GAAE,OAAe,EACxC,mBAAmB,wCAA8C;IAGnF;;;;;;;;;OASG;IACI,OAAO,CAAC,CAAC,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,MAAM,GAAE,MAAW,GAAG,CAAC;IA0BjE,OAAO,CAAC,WAAW;IAoBZ,OAAO,CAAC,KAAK,CAAC,EAAE,KAAK,GAAG,SAAS,GAAG,IAAI;CAG/C"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sampledTelemetryHelper.js","sourceRoot":"","sources":["../src/sampledTelemetryHelper.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"sampledTelemetryHelper.js","sourceRoot":"","sources":["../src/sampledTelemetryHelper.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AA0C3D;;;;;;;;;;GAUG;AACH,MAAM,OAAO,sBAAsB;IAKlC;;;;;;;;;;;;;;;;;OAiBG;IACH,YACkB,SAAoC,EACpC,MAA2B,EAC3B,eAAuB,EACvB,0BAAmC,KAAK,EACxC,sBAAsB,IAAI,GAAG,EAAoC;QAJjE,cAAS,GAAT,SAAS,CAA2B;QACpC,WAAM,GAAN,MAAM,CAAqB;QAC3B,oBAAe,GAAf,eAAe,CAAQ;QACvB,4BAAuB,GAAvB,uBAAuB,CAAiB;QACxC,wBAAmB,GAAnB,mBAAmB,CAA8C;QA3BnF,aAAQ,GAAY,KAAK,CAAC;QAET,oBAAe,GAAG,IAAI,GAAG,EAAwB,CAAC;IA0BhE,CAAC;IAEJ;;;;;;;;;OASG;IACI,OAAO,CAAI,aAAsB,EAAE,SAAiB,EAAE;QAC5D,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAChC,MAAM,WAAW,GAAG,aAAa,EAAE,CAAC;QACpC,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;QAE3C,IAAI,CAAC,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACzC,IAAI,CAAC,KAAK,SAAS,EAAE;YACpB,CAAC,GAAG,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,CAAC;YAC/B,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;SACpC;QACD,CAAC,CAAC,KAAK,EAAE,CAAC;QACV,CAAC,CAAC,QAAQ,GAAG,QAAQ,CAAC;QAEtB,IAAI,IAAI,CAAC,uBAAuB,EAAE;YACjC,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,aAAa,IAAI,CAAC,CAAC,GAAG,QAAQ,CAAC;YACpD,CAAC,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,IAAI,QAAQ,EAAE,QAAQ,CAAC,CAAC;YAC9D,CAAC,CAAC,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,EAAE,QAAQ,CAAC,CAAC;SACvD;QAED,IAAI,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,eAAe,EAAE;YACpC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;SACzB;QAED,OAAO,WAAW,CAAC;IACpB,CAAC;IAEO,WAAW,CAAC,MAAc;QACjC,MAAM,YAAY,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACtD,IAAI,YAAY,KAAK,SAAS,EAAE;YAC/B,OAAO;SACP;QAED,IAAI,YAAY,CAAC,KAAK,KAAK,CAAC,EAAE;YAC7B,MAAM,gBAAgB,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YAE9D,MAAM,cAAc,GAAkC;gBACrD,GAAG,IAAI,CAAC,SAAS;gBACjB,GAAG,gBAAgB;gBACnB,GAAG,YAAY;aACf,CAAC;YAEF,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,cAAc,CAAC,CAAC;YACjD,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;SACpC;IACF,CAAC;IAEM,OAAO,CAAC,KAAyB;QACvC,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,eAAe,CAAC,OAAO,EAAE;YAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IACvE,CAAC;CACD","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { performance } from \"@fluid-internal/client-utils\";\nimport type { IDisposable, ITelemetryBaseProperties } from \"@fluidframework/core-interfaces\";\nimport {\n\ttype ITelemetryGenericEventExt,\n\tITelemetryLoggerExt,\n\ttype ITelemetryPerformanceEventExt,\n} from \"./telemetryTypes.js\";\n\n/**\n * @privateRemarks\n *\n * The names of the properties in this interface are the ones that will get stamped in the\n * telemetry event, changes should be considered carefully. The optional properties should\n * only be populated if 'includeAggregateMetrics' is true.\n */\ninterface Measurements {\n\t/**\n\t * The duration of the latest execution.\n\t */\n\tduration: number;\n\n\t/**\n\t * The number of executions since the last time an event was generated.\n\t */\n\tcount: number;\n\n\t/**\n\t * Total duration across all the executions since the last event was generated.\n\t */\n\ttotalDuration?: number;\n\n\t/**\n\t * Min duration across all the executions since the last event was generated.\n\t */\n\tminDuration?: number;\n\n\t/**\n\t * Max duration across all the executions since the last event was generated.\n\t */\n\tmaxDuration?: number;\n}\n\n/**\n * Helper class that executes a specified code block and writes an\n * {@link @fluidframework/core-interfaces#ITelemetryPerformanceEvent} to a specified logger every time a specified\n * number of executions is reached (or when the class is disposed).\n *\n * The `duration` field in the telemetry event is the duration of the latest execution (sample) of the specified\n * function. See the documentation of the `includeAggregateMetrics` parameter for additional details that can be\n * included.\n *\n * @internal\n */\nexport class SampledTelemetryHelper implements IDisposable {\n\tdisposed: boolean = false;\n\n\tprivate readonly measurementsMap = new Map<string, Measurements>();\n\n\t/**\n\t * @param eventBase -\n\t * Custom properties to include in the telemetry performance event when it is written.\n\t * @param logger -\n\t * The logger to use to write the telemetry performance event.\n\t * @param sampleThreshold -\n\t * Telemetry performance events will be generated every time we hit this many executions of the code block.\n\t * @param includeAggregateMetrics -\n\t * If set to `true`, the telemetry performance event will include aggregated metrics (total duration, min duration,\n\t * max duration) for all the executions in between generated events.\n\t * @param perBucketProperties -\n\t * Map of strings that represent different buckets (which can be specified when calling the 'measure' method), to\n\t * properties which should be added to the telemetry event for that bucket. If a bucket being measured does not\n\t * have an entry in this map, no additional properties will be added to its telemetry events. The following keys are\n\t * reserved for use by this class: \"duration\", \"count\", \"totalDuration\", \"minDuration\", \"maxDuration\". If any of\n\t * them is specified as a key in one of the ITelemetryBaseProperties objects in this map, that key-value pair will be\n\t * ignored.\n\t */\n\tpublic constructor(\n\t\tprivate readonly eventBase: ITelemetryGenericEventExt,\n\t\tprivate readonly logger: ITelemetryLoggerExt,\n\t\tprivate readonly sampleThreshold: number,\n\t\tprivate readonly includeAggregateMetrics: boolean = false,\n\t\tprivate readonly perBucketProperties = new Map<string, ITelemetryBaseProperties>(),\n\t) {}\n\n\t/**\n\t * Executes the specified code and keeps track of execution time statistics.\n\t * If it's been called enough times (the sampleThreshold for the class) then it generates a log message with the necessary information.\n\t *\n\t * @param codeToMeasure - The code to be executed and measured.\n\t * @param bucket - A key to track executions of the code block separately.\n\t * Each different value of this parameter has a separate set of executions and metrics tracked by the class.\n\t * If no such distinction needs to be made, do not provide a value.\n\t * @returns Whatever the passed-in code block returns.\n\t */\n\tpublic measure<T>(codeToMeasure: () => T, bucket: string = \"\"): T {\n\t\tconst start = performance.now();\n\t\tconst returnValue = codeToMeasure();\n\t\tconst duration = performance.now() - start;\n\n\t\tlet m = this.measurementsMap.get(bucket);\n\t\tif (m === undefined) {\n\t\t\tm = { count: 0, duration: -1 };\n\t\t\tthis.measurementsMap.set(bucket, m);\n\t\t}\n\t\tm.count++;\n\t\tm.duration = duration;\n\n\t\tif (this.includeAggregateMetrics) {\n\t\t\tm.totalDuration = (m.totalDuration ?? 0) + duration;\n\t\t\tm.minDuration = Math.min(m.minDuration ?? duration, duration);\n\t\t\tm.maxDuration = Math.max(m.maxDuration ?? 0, duration);\n\t\t}\n\n\t\tif (m.count >= this.sampleThreshold) {\n\t\t\tthis.flushBucket(bucket);\n\t\t}\n\n\t\treturn returnValue;\n\t}\n\n\tprivate flushBucket(bucket: string): void {\n\t\tconst measurements = this.measurementsMap.get(bucket);\n\t\tif (measurements === undefined) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (measurements.count !== 0) {\n\t\t\tconst bucketProperties = this.perBucketProperties.get(bucket);\n\n\t\t\tconst telemetryEvent: ITelemetryPerformanceEventExt = {\n\t\t\t\t...this.eventBase,\n\t\t\t\t...bucketProperties, // If the bucket doesn't exist and this is undefined, things work as expected\n\t\t\t\t...measurements,\n\t\t\t};\n\n\t\t\tthis.logger.sendPerformanceEvent(telemetryEvent);\n\t\t\tthis.measurementsMap.delete(bucket);\n\t\t}\n\t}\n\n\tpublic dispose(error?: Error | undefined): void {\n\t\tfor (const [k] of this.measurementsMap.entries()) this.flushBucket(k);\n\t}\n}\n"]}
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
import { strict as assert } from "node:assert";
|
|
13
13
|
import sinon from "sinon";
|
|
14
14
|
import { v4 as uuid } from "uuid";
|
|
15
|
-
import {
|
|
16
|
-
import { LoggingError, isTaggedTelemetryPropertyValue, normalizeError, wrapError, wrapErrorAndLog, extractLogSafeErrorProperties, isExternalError, } from "../errorLogging.js";
|
|
15
|
+
import { LoggingError, extractLogSafeErrorProperties, isExternalError, isTaggedTelemetryPropertyValue, normalizeError, wrapError, wrapErrorAndLog, } from "../errorLogging.js";
|
|
17
16
|
import { hasErrorInstanceId, isFluidError, isValidLegacyError, } from "../fluidErrorBase.js";
|
|
17
|
+
import { TaggedLoggerAdapter, TelemetryDataTag, TelemetryLogger } from "../logger.js";
|
|
18
18
|
import { MockLogger } from "../mockLogger.js";
|
|
19
19
|
describe("Error Logging", () => {
|
|
20
20
|
describe("TelemetryLogger.prepareErrorObject", () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errorLogging.spec.js","sourceRoot":"","sources":["../../src/test/errorLogging.spec.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\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-unsafe-argument */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-unsafe-call */\n/* eslint-disable unicorn/consistent-function-scoping */\n/* eslint-disable unicorn/no-null */\n\nimport { strict as assert } from \"node:assert\";\nimport sinon from \"sinon\";\nimport { v4 as uuid } from \"uuid\";\nimport type {\n\tITelemetryBaseEvent,\n\tITelemetryBaseProperties,\n} from \"@fluidframework/core-interfaces\";\nimport { TelemetryDataTag, TelemetryLogger, TaggedLoggerAdapter } from \"../logger.js\";\nimport {\n\tLoggingError,\n\tisTaggedTelemetryPropertyValue,\n\tnormalizeError,\n\tIFluidErrorAnnotations,\n\twrapError,\n\twrapErrorAndLog,\n\textractLogSafeErrorProperties,\n\tisExternalError,\n} from \"../errorLogging.js\";\nimport {\n\thasErrorInstanceId,\n\tIFluidErrorBase,\n\tisFluidError,\n\tisValidLegacyError,\n} from \"../fluidErrorBase.js\";\nimport { MockLogger } from \"../mockLogger.js\";\nimport type { ITelemetryPropertiesExt } from \"../telemetryTypes.js\";\n\ndescribe(\"Error Logging\", () => {\n\tdescribe(\"TelemetryLogger.prepareErrorObject\", () => {\n\t\tfunction freshEvent(): ITelemetryBaseEvent {\n\t\t\treturn { category: \"cat1\", eventName: \"event1\" };\n\t\t}\n\t\tfunction createILoggingError(props: ITelemetryBaseProperties): {\n\t\t\tgetTelemetryProperties: () => ITelemetryBaseProperties;\n\t\t} {\n\t\t\treturn { ...props, getTelemetryProperties: (): ITelemetryBaseProperties => props };\n\t\t}\n\n\t\tit(\"non-object error added to event\", () => {\n\t\t\tlet event = freshEvent();\n\t\t\tTelemetryLogger.prepareErrorObject(event, \"hello\", false);\n\t\t\tassert.strictEqual(event.error, \"hello\", \"string should work\");\n\t\t\tevent = freshEvent();\n\t\t\tTelemetryLogger.prepareErrorObject(event, 42, false);\n\t\t\tassert.strictEqual(event.error, \"42\", \"number should work\");\n\t\t\tevent = freshEvent();\n\t\t\tTelemetryLogger.prepareErrorObject(event, true, false);\n\t\t\tassert.strictEqual(event.error, \"true\", \"boolean should work\");\n\t\t\tevent = freshEvent();\n\t\t\tTelemetryLogger.prepareErrorObject(event, undefined, false);\n\t\t\tassert.strictEqual(event.error, \"undefined\", \"undefined should work\");\n\n\t\t\t// Technically this violates TelemetryBaseEventPropertyType's type constraint but it's actually supported\n\t\t\tevent = freshEvent();\n\t\t\tTelemetryLogger.prepareErrorObject(event, null, false);\n\t\t\tassert.strictEqual(event.error, \"null\", \"null should work\");\n\t\t});\n\t\tit(\"stack and message added to event (stack should exclude message)\", () => {\n\t\t\tconst event = freshEvent();\n\t\t\tconst error = new Error(\"boom\");\n\t\t\terror.name = \"MyErrorName\";\n\t\t\tTelemetryLogger.prepareErrorObject(event, error, false);\n\t\t\tassert(event.error === \"boom\");\n\t\t\tassert((event.stack as string).includes(\"MyErrorName\"));\n\t\t\tassert(!(event.stack as string).includes(\"boom\"));\n\t\t});\n\t\tit(\"containsPII (legacy) is ignored\", () => {\n\t\t\t// Previously, setting containsPII = true on an error obj would (attempt to) redact its message\n\t\t\tconst event = freshEvent();\n\t\t\tconst error = new Error(\"boom\");\n\t\t\terror.name = \"MyErrorName\";\n\t\t\t(error as any).containsPII = true;\n\t\t\tTelemetryLogger.prepareErrorObject(event, error, false);\n\t\t\tassert(event.error === \"boom\");\n\t\t\tassert((event.stack as string).includes(\"MyErrorName\"));\n\t\t});\n\t\tit(\"getTelemetryProperties - tags on overwritten Error base props\", () => {\n\t\t\tconst event = freshEvent();\n\t\t\tconst error = createILoggingError({\n\t\t\t\tmessage: { value: \"Mark Fields\", tag: \"UserData\" }, // hopefully no one does this!\n\t\t\t\tstack: { value: \"tagged\", tag: TelemetryDataTag.CodeArtifact },\n\t\t\t});\n\t\t\tTelemetryLogger.prepareErrorObject(event, error, false);\n\t\t\tassert.deepStrictEqual(event.message, { value: \"Mark Fields\", tag: \"UserData\" });\n\t\t\tassert.deepStrictEqual(event.error, \"[object Object]\"); // weird but ok\n\t\t\tassert.deepStrictEqual(event.stack, {\n\t\t\t\tvalue: \"tagged\",\n\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t});\n\t\t});\n\t\tit(\"getTelemetryProperties absent - no further props added\", () => {\n\t\t\tconst event = freshEvent();\n\t\t\tconst error = { ...new Error(\"boom\"), foo: \"foo\", bar: 2 };\n\t\t\tTelemetryLogger.prepareErrorObject(event, error, false);\n\t\t\tassert(event.foo === undefined && event.bar === undefined);\n\t\t});\n\t\tit(\"getTelemetryProperties overlaps event - do not overwrite\", () => {\n\t\t\tconst event = { ...freshEvent(), foo: \"event_foo\", bar: 42 };\n\t\t\tconst error = createILoggingError({ foo: \"error_foo\", bar: -1 });\n\t\t\tTelemetryLogger.prepareErrorObject(event, error, false);\n\t\t\tassert(event.foo === \"event_foo\" && event.bar === 42);\n\t\t});\n\t\tit(\"getTelemetryProperties present - add additional props\", () => {\n\t\t\tconst event = freshEvent();\n\t\t\tconst error = createILoggingError({ foo: \"foo\", bar: 2 });\n\t\t\tTelemetryLogger.prepareErrorObject(event, error, false);\n\t\t\tassert(event.foo === \"foo\" && event.bar === 2);\n\t\t});\n\t\tit(\"fetchStack false - Don't add a stack if missing\", () => {\n\t\t\tconst event = freshEvent();\n\t\t\tconst error = { message: \"I have no stack\" };\n\t\t\tTelemetryLogger.prepareErrorObject(event, error, false);\n\t\t\tassert.strictEqual(event.stack, undefined);\n\t\t});\n\t\tit(\"fetchStack true - Don't add a stack if present\", () => {\n\t\t\tconst event = freshEvent();\n\t\t\tconst error = new Error(\"boom\");\n\t\t\terror.name = \"MyName\";\n\t\t\tTelemetryLogger.prepareErrorObject(event, error, false);\n\t\t\tassert((event.stack as string).includes(\"MyName\"));\n\t\t});\n\t\tit(\"fetchStack true - Add a stack if missing\", () => {\n\t\t\tconst event = freshEvent();\n\t\t\tconst error = { message: \"I have no stack - boom\", name: \"MyName\" };\n\t\t\tTelemetryLogger.prepareErrorObject(event, error, true);\n\t\t\tassert.strictEqual(typeof event.stack, \"string\");\n\t\t\tassert(!(event.stack as string).includes(\"MyName\"));\n\t\t});\n\t});\n\tdescribe(\"TaggedLoggerAdapter\", () => {\n\t\tconst events: ITelemetryBaseEvent[] = [];\n\t\tclass TestTelemetryLogger extends TelemetryLogger {\n\t\t\tpublic events: ITelemetryBaseEvent[] = [];\n\t\t\tpublic send(event: ITelemetryBaseEvent): void {\n\t\t\t\tevents.push(this.prepareEvent(event));\n\t\t\t}\n\t\t}\n\t\tconst adaptedLogger = new TaggedLoggerAdapter(new TestTelemetryLogger(\"namespace\"));\n\n\t\tit(\"TaggedLoggerAdapter - tagged UserData is removed\", () => {\n\t\t\tconst event = {\n\t\t\t\tcategory: \"cat\",\n\t\t\t\teventName: \"event\",\n\t\t\t\tuserDataObject: {\n\t\t\t\t\ttag: TelemetryDataTag.UserData,\n\t\t\t\t\tvalue: \"someUserData\",\n\t\t\t\t},\n\t\t\t};\n\t\t\tadaptedLogger.send(event);\n\t\t\tassert.strictEqual(\n\t\t\t\tevents[0].userDataObject,\n\t\t\t\t\"REDACTED (UserData)\",\n\t\t\t\t\"someUserData should be redacted\",\n\t\t\t);\n\t\t\tevents.pop();\n\t\t});\n\t\tit(\"TaggedLoggerAdapter - tagged CodeArtifact are preserved\", () => {\n\t\t\tconst event = {\n\t\t\t\tcategory: \"cat\",\n\t\t\t\teventName: \"event\",\n\t\t\t\tpackageDataObject: {\n\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t\tvalue: \"somePackageData\",\n\t\t\t\t},\n\t\t\t};\n\t\t\tadaptedLogger.send(event);\n\t\t\tassert.strictEqual(\n\t\t\t\tevents[0].packageDataObject,\n\t\t\t\t\"somePackageData\",\n\t\t\t\t\"somePackageData should be preserved\",\n\t\t\t);\n\t\t\tevents.pop();\n\t\t});\n\t\tit(\"TaggedLoggerAdapter - tagged [unrecognized tag] are removed\", () => {\n\t\t\tconst event = {\n\t\t\t\tcategory: \"cat\",\n\t\t\t\teventName: \"event\",\n\t\t\t\tunknownTaggedObject: {\n\t\t\t\t\ttag: \"someUnknownTag\",\n\t\t\t\t\tvalue: \"someEvilData\",\n\t\t\t\t},\n\t\t\t};\n\t\t\tadaptedLogger.send(event);\n\t\t\tassert.strictEqual(\n\t\t\t\tevents[0].unknownTaggedObject,\n\t\t\t\t\"REDACTED (unknown tag)\",\n\t\t\t\t\"someUnknownTag should be redacted\",\n\t\t\t);\n\t\t\tevents.pop();\n\t\t});\n\t});\n\tdescribe(\"TaggedTelemetryData\", () => {\n\t\tit(\"Ensure backwards compatibility\", () => {\n\t\t\t// The values of the enum should never change (even if the keys are renamed)\n\t\t\tassert(TelemetryDataTag.CodeArtifact === (\"CodeArtifact\" as TelemetryDataTag));\n\t\t\tassert(TelemetryDataTag.UserData === (\"UserData\" as TelemetryDataTag));\n\t\t});\n\t});\n\tdescribe(\"isTaggedTelemetryPropertyValue\", () => {\n\t\tit(\"non-object input not ok\", () => {\n\t\t\tassert.strictEqual(isTaggedTelemetryPropertyValue(\"hello\"), false);\n\t\t\tassert.strictEqual(isTaggedTelemetryPropertyValue(123), false);\n\t\t\tassert.strictEqual(isTaggedTelemetryPropertyValue(false), false);\n\t\t\tassert.strictEqual(isTaggedTelemetryPropertyValue(undefined), false);\n\t\t\tassert.strictEqual(isTaggedTelemetryPropertyValue(null as any), false);\n\t\t\tassert.strictEqual(\n\t\t\t\tisTaggedTelemetryPropertyValue(function x() {\n\t\t\t\t\treturn 54;\n\t\t\t\t} as any),\n\t\t\t\tfalse,\n\t\t\t);\n\t\t\tassert.strictEqual(isTaggedTelemetryPropertyValue(Symbol(\"okay\") as any), false);\n\t\t});\n\t\tit(\"non-object value ok\", () => {\n\t\t\tassert.strictEqual(\n\t\t\t\tisTaggedTelemetryPropertyValue({ value: \"hello\", tag: \"any string\" }),\n\t\t\t\ttrue,\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\tisTaggedTelemetryPropertyValue({ value: 123, tag: \"any string\" }),\n\t\t\t\ttrue,\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\tisTaggedTelemetryPropertyValue({ value: false, tag: \"any string\" }),\n\t\t\t\ttrue,\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\tisTaggedTelemetryPropertyValue({ value: undefined, tag: \"any string\" }),\n\t\t\t\ttrue,\n\t\t\t);\n\t\t});\n\t\tit(\"Check result for various invalid inputs (per typings)\", () => {\n\t\t\tassert.strictEqual(\n\t\t\t\tisTaggedTelemetryPropertyValue({ tag: \"any string\" } as any),\n\t\t\t\ttrue,\n\t\t\t\t\"value prop may be absent\",\n\t\t\t);\n\t\t\t// The type guard used is a bit imprecise. Here is proof (these \"shouldn't\" be ok)\n\t\t\tassert.strictEqual(\n\t\t\t\tisTaggedTelemetryPropertyValue({\n\t\t\t\t\tvalue: function x() {\n\t\t\t\t\t\treturn 54;\n\t\t\t\t\t} as any,\n\t\t\t\t\ttag: \"any string\",\n\t\t\t\t}),\n\t\t\t\ttrue,\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\tisTaggedTelemetryPropertyValue({ value: Symbol(\"okay\") as any, tag: \"any string\" }),\n\t\t\t\ttrue,\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\tisTaggedTelemetryPropertyValue({ value: \"hello\", tag: 1 } as any),\n\t\t\t\tfalse,\n\t\t\t\t\"number tag is bad\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\tisTaggedTelemetryPropertyValue({ value: \"hello\", tag: false } as any),\n\t\t\t\tfalse,\n\t\t\t\t\"boolean tag is bad\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\tisTaggedTelemetryPropertyValue({ value: \"hello\", tag: {} } as any),\n\t\t\t\tfalse,\n\t\t\t\t\"object tag is bad\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\tisTaggedTelemetryPropertyValue({ value: \"hello\", tag: null } as any),\n\t\t\t\tfalse,\n\t\t\t\t\"null tag is bad\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\tisTaggedTelemetryPropertyValue({ value: \"hello\" } as any),\n\t\t\t\tfalse,\n\t\t\t\t\"undefined (missing) tag is bad\",\n\t\t\t);\n\t\t});\n\t});\n\tdescribe(\"LoggingError\", () => {\n\t\tit(\"ctor props are assigned to the object\", () => {\n\t\t\tconst loggingError = new LoggingError(\"myMessage\", {\n\t\t\t\tp1: 1,\n\t\t\t\tp2: \"two\",\n\t\t\t\tp3: true,\n\t\t\t\ttagged: { value: 4, tag: \"CodeArtifact\" },\n\t\t\t});\n\t\t\tconst errorAsAny = loggingError as any;\n\t\t\tassert.strictEqual(errorAsAny.message, \"myMessage\");\n\t\t\tassert.strictEqual(errorAsAny.p1, 1);\n\t\t\tassert.strictEqual(errorAsAny.p2, \"two\");\n\t\t\tassert.strictEqual(errorAsAny.p3, true);\n\t\t\tassert.deepStrictEqual(errorAsAny.tagged, { value: 4, tag: \"CodeArtifact\" });\n\t\t});\n\t\tit(\"errorInstanceId unique each time\", () => {\n\t\t\tconst e1 = new LoggingError(\"1\");\n\t\t\tconst e2 = new LoggingError(\"2\");\n\t\t\tassert.equal(e1.errorInstanceId.length, 36, \"should be guid-length\");\n\t\t\tassert.equal(e2.errorInstanceId.length, 36, \"should be guid-length\");\n\t\t\tassert.notEqual(\n\t\t\t\te1.errorInstanceId,\n\t\t\t\te2.errorInstanceId,\n\t\t\t\t\"each error instance should get unique id\",\n\t\t\t);\n\t\t});\n\t\tit(\"getTelemetryProperties extracts all untagged ctor props\", () => {\n\t\t\tconst loggingError = new LoggingError(\"myMessage\", { p1: 1, p2: \"two\", p3: true });\n\t\t\tconst props = loggingError.getTelemetryProperties();\n\t\t\tassert.strictEqual(props.message, \"myMessage\");\n\t\t\tassert.strictEqual(typeof props.stack, \"string\");\n\t\t\tassert.strictEqual(props.name, undefined); // Error.name is not logged\n\t\t\tassert.strictEqual(props.p1, 1);\n\t\t\tassert.strictEqual(props.p2, \"two\");\n\t\t\tassert.strictEqual(props.p3, true);\n\t\t});\n\t\tit(\"getTelemetryProperties respects omitPropsFromLogging\", () => {\n\t\t\tconst loggingError = new LoggingError(\"myMessage\", {}, new Set([\"foo\"]));\n\t\t\t(loggingError as any).foo = \"secrets!\";\n\t\t\t(loggingError as any).bar = \"normal\";\n\t\t\tconst props = loggingError.getTelemetryProperties();\n\t\t\tassert.strictEqual(\n\t\t\t\tprops.omitPropsFromLogging,\n\t\t\t\tundefined,\n\t\t\t\t\"omitPropsFromLogging itself should be omitted\",\n\t\t\t);\n\t\t\tassert.strictEqual(props.foo, undefined, \"foo should have been omitted\");\n\t\t\tassert.strictEqual(props.bar, \"normal\", \"bar should not be omitted\");\n\t\t});\n\t\tit(\"addTelemetryProperties - adds to object, returned from getTelemetryProperties, doesn't overwrite\", () => {\n\t\t\tconst loggingError = new LoggingError(\"myMessage\", { p1: 1, p2: \"two\", p3: true });\n\t\t\t(loggingError as any).p1 = \"should not be overwritten\";\n\t\t\tloggingError.addTelemetryProperties({\n\t\t\t\tp1: \"ignored\",\n\t\t\t\tp4: 4,\n\t\t\t\tp5: true,\n\t\t\t\tp6: { value: 5, tag: \"CodeArtifact\" },\n\t\t\t\tp7: [\"a\", \"b\", \"c\"],\n\t\t\t\tp8: [1, 2, 3],\n\t\t\t\tp9: [true, true, false],\n\t\t\t\tp10: { one: \"1\" },\n\t\t\t\tp11: undefined,\n\t\t\t\tp12: { value: [\"1\", 2, true], tag: \"CodeArtifact\" },\n\t\t\t});\n\t\t\tconst props = loggingError.getTelemetryProperties();\n\t\t\tassert.strictEqual(props.p1, \"should not be overwritten\");\n\t\t\tassert.strictEqual(props.p4, 4);\n\t\t\tassert.strictEqual(props.p5, true);\n\t\t\tassert.deepStrictEqual(props.p6, { value: 5, tag: \"CodeArtifact\" });\n\t\t\tassert.strictEqual(props.p7, '[\"a\",\"b\",\"c\"]');\n\t\t\tassert.strictEqual(props.p8, \"[1,2,3]\");\n\t\t\tassert.strictEqual(props.p9, \"[true,true,false]\");\n\t\t\tassert.strictEqual(props.p10, `{\"one\":\"1\"}`);\n\t\t\tassert.strictEqual(props.p11, undefined);\n\t\t\tassert.deepStrictEqual(props.p12, { value: `[\"1\",2,true]`, tag: \"CodeArtifact\" });\n\t\t\tconst errorAsAny = loggingError as any;\n\t\t\tassert.strictEqual(errorAsAny.p1, \"should not be overwritten\");\n\t\t\tassert.strictEqual(errorAsAny.p4, 4);\n\t\t\tassert.strictEqual(errorAsAny.p5, true);\n\t\t\tassert.deepStrictEqual(errorAsAny.p6, { value: 5, tag: \"CodeArtifact\" });\n\t\t\tassert.deepStrictEqual(errorAsAny.p7, [\"a\", \"b\", \"c\"]);\n\t\t\tassert.deepStrictEqual(errorAsAny.p8, [1, 2, 3]);\n\t\t\tassert.deepStrictEqual(errorAsAny.p9, [true, true, false]);\n\t\t\tassert.deepStrictEqual(errorAsAny.p10, { one: \"1\" });\n\t\t\tassert.strictEqual(errorAsAny.p11, undefined);\n\t\t\tassert.deepStrictEqual(errorAsAny.p12, { value: [\"1\", 2, true], tag: \"CodeArtifact\" });\n\t\t});\n\t\tit(\"Set valid props via 'as any' - returned from getTelemetryProperties, overwrites\", () => {\n\t\t\tconst loggingError = new LoggingError(\"myMessage\", { p1: 1, p2: \"two\", p3: true });\n\t\t\tloggingError.addTelemetryProperties({ p1: \"should be overwritten\" });\n\t\t\tconst errorAsAny = loggingError as any;\n\t\t\t// Things that could be set with addTelemetryProperties\n\t\t\terrorAsAny.p1 = \"one\";\n\t\t\terrorAsAny.p4 = 4;\n\t\t\terrorAsAny.p5 = true;\n\t\t\terrorAsAny.p6 = { value: 5, tag: \"CodeArtifact\" };\n\t\t\terrorAsAny.userData6 = { value: 5, tag: \"UserData\" };\n\t\t\terrorAsAny.p7 = [\"a\", \"b\", \"c\"];\n\t\t\terrorAsAny.p8 = [1, 2, 3];\n\t\t\terrorAsAny.p9 = [true, true, false];\n\t\t\terrorAsAny.p10 = { one: \"1\" };\n\t\t\terrorAsAny.p11 = undefined;\n\t\t\terrorAsAny.p12 = { value: [\"1\", 2, true], tag: \"CodeArtifact\" };\n\t\t\t// Things that can't be set with addTelemetryProperties\n\t\t\terrorAsAny.p13 = null; // Null\n\t\t\terrorAsAny.p14 = [\"a\", \"b\", \"c\", null]; // Array with nulls\n\t\t\terrorAsAny.p15 = [[1, 2]]; // Nested array\n\t\t\tconst props = loggingError.getTelemetryProperties();\n\t\t\tassert.strictEqual(props.p1, \"one\");\n\t\t\tassert.strictEqual(props.p4, 4);\n\t\t\tassert.strictEqual(props.p5, true);\n\t\t\tassert.deepStrictEqual(props.p6, { value: 5, tag: \"CodeArtifact\" });\n\t\t\tassert.deepStrictEqual(props.userData6, { value: 5, tag: \"UserData\" });\n\t\t\tassert.strictEqual(props.p7, `[\"a\",\"b\",\"c\"]`);\n\t\t\tassert.strictEqual(props.p8, `[1,2,3]`);\n\t\t\tassert.strictEqual(props.p9, `[true,true,false]`);\n\t\t\tassert.strictEqual(props.p10, `{\"one\":\"1\"}`);\n\t\t\tassert.strictEqual(props.p11, undefined);\n\t\t\tassert.deepStrictEqual(props.p12, { value: `[\"1\",2,true]`, tag: \"CodeArtifact\" });\n\t\t\tassert.strictEqual(props.p13, \"null\");\n\t\t\tassert.strictEqual(props.p14, `[\"a\",\"b\",\"c\",null]`);\n\t\t\tassert.strictEqual(props.p15, \"[[1,2]]\");\n\t\t});\n\t\tit(\"addTelemetryProperties - Does not overwrite base class Error fields (untagged)\", () => {\n\t\t\tconst loggingError = new LoggingError(\"myMessage\");\n\t\t\tconst propsWillBeIgnored = { message: \"surprise1\", stack: \"surprise2\" };\n\t\t\tloggingError.addTelemetryProperties(propsWillBeIgnored);\n\t\t\tconst props = loggingError.getTelemetryProperties();\n\t\t\tdelete props.fluidErrorCode; // It's on there for back compat, not trying to test it here\n\t\t\tconst { message, stack, errorInstanceId } = loggingError;\n\t\t\tassert.deepStrictEqual(\n\t\t\t\tprops,\n\t\t\t\t{ message, stack, errorInstanceId },\n\t\t\t\t\"addTelemetryProperties should not overwrite existing props\",\n\t\t\t);\n\t\t});\n\t\tit(\"addTelemetryProperties - Does not overwrite base class Error fields (tagged)\", () => {\n\t\t\tconst loggingError = new LoggingError(\"myMessage\");\n\t\t\tconst propsWillBeIgnored = {\n\t\t\t\tmessage: { value: \"Mark Fields\", tag: \"UserData\" },\n\t\t\t\tstack: { value: \"surprise2\", tag: \"CodeArtifact\" },\n\t\t\t};\n\t\t\tloggingError.addTelemetryProperties(propsWillBeIgnored);\n\t\t\tconst props = loggingError.getTelemetryProperties();\n\t\t\tdelete props.fluidErrorCode; // It's on there for back compat, not trying to test it here\n\t\t\tconst { message, stack, errorInstanceId } = loggingError;\n\t\t\tassert.deepStrictEqual(\n\t\t\t\tprops,\n\t\t\t\t{ message, stack, errorInstanceId },\n\t\t\t\t\"addTelemetryProperties should not overwrite existing props\",\n\t\t\t);\n\t\t});\n\t\tit(\"addTelemetryProperties - Does not overwrite existing telemetry props\", () => {\n\t\t\tconst loggingError = new LoggingError(\"myMessage\", { p1: 1 });\n\t\t\tloggingError.addTelemetryProperties({ p1: \"one\" });\n\t\t\tassert(loggingError.getTelemetryProperties().p1 === 1);\n\t\t\tloggingError.addTelemetryProperties({ p1: \"uno\" });\n\t\t\tassert(loggingError.getTelemetryProperties().p1 === 1);\n\t\t});\n\t\tit(\"typeCheck - Correctly type checks an instace of LoggingError\", () => {\n\t\t\tconst loggingError = new LoggingError(\"myMessage\", { p1: 1 });\n\t\t\tconst normalizedLoggingError = normalizeError(loggingError);\n\t\t\tconst basicError = new Error(\"basicErrorMessage\");\n\t\t\tassert.strictEqual(\n\t\t\t\tLoggingError.typeCheck(loggingError),\n\t\t\t\ttrue,\n\t\t\t\t\"LoggingError is a LoggingError\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\tLoggingError.typeCheck(normalizedLoggingError),\n\t\t\t\ttrue,\n\t\t\t\t\"Normalized Error is a LoggingError\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\tLoggingError.typeCheck(basicError),\n\t\t\t\tfalse,\n\t\t\t\t\"Error is not a LoggingError\",\n\t\t\t);\n\t\t});\n\t});\n\tdescribe(\"extractLogSafeErrorProperties\", () => {\n\t\tfunction createSampleError(): Error {\n\t\t\ttry {\n\t\t\t\tconst error = new Error(\"asdf\");\n\t\t\t\terror.name = \"FooError\";\n\t\t\t\tthrow error;\n\t\t\t} catch (error) {\n\t\t\t\treturn error as Error;\n\t\t\t}\n\t\t}\n\n\t\tit(\"non-object error yields correct message\", () => {\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties(\"hello\", false /* sanitizeStack */).message,\n\t\t\t\t\"hello\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties(42, false /* sanitizeStack */).message,\n\t\t\t\t\"42\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties(true, false /* sanitizeStack */).message,\n\t\t\t\t\"true\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties(undefined, false /* sanitizeStack */).message,\n\t\t\t\t\"undefined\",\n\t\t\t);\n\t\t});\n\t\tit(\"object error yields correct message\", () => {\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties({ message: \"hello\" }, false /* sanitizeStack */)\n\t\t\t\t\t.message,\n\t\t\t\t\"hello\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties({ message: 42 }, false /* sanitizeStack */).message,\n\t\t\t\t\"[object Object]\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties({ foo: 42 }, false /* sanitizeStack */).message,\n\t\t\t\t\"[object Object]\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties([1, 2, 3], false /* sanitizeStack */).message,\n\t\t\t\t\"1,2,3\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties(null, false /* sanitizeStack */).message,\n\t\t\t\t\"null\",\n\t\t\t);\n\t\t});\n\t\tit(\"extract errorType\", () => {\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties({ errorType: \"hello\" }, false /* sanitizeStack */)\n\t\t\t\t\t.errorType,\n\t\t\t\t\"hello\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties({ foo: \"hello\" }, false /* sanitizeStack */)\n\t\t\t\t\t.errorType,\n\t\t\t\tundefined,\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties({ errorType: 42 }, false /* sanitizeStack */)\n\t\t\t\t\t.errorType,\n\t\t\t\tundefined,\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties(42, false /* sanitizeStack */).errorType,\n\t\t\t\tundefined,\n\t\t\t);\n\t\t});\n\t\tit(\"extract stack\", () => {\n\t\t\tconst e1 = createSampleError();\n\n\t\t\tconst stack = extractLogSafeErrorProperties(e1, false /* sanitizeStack */).stack;\n\t\t\tassert(typeof stack === \"string\");\n\t\t\tassert(stack?.includes(\"asdf\"), \"stack is expected to contain the message\");\n\t\t\tassert(stack?.includes(\"FooError\"), \"stack is expected to contain the name\");\n\n\t\t\tconst sanitizedStack = extractLogSafeErrorProperties(\n\t\t\t\te1,\n\t\t\t\ttrue /* sanitizeStack */,\n\t\t\t).stack;\n\t\t\tassert(typeof sanitizedStack === \"string\");\n\t\t\tassert(\n\t\t\t\t!sanitizedStack?.includes(\"asdf\"),\n\t\t\t\t\"message should have been removed from sanitized stack\",\n\t\t\t);\n\t\t\tassert(\n\t\t\t\tsanitizedStack?.includes(\"FooError\"),\n\t\t\t\t\"name should still be in the sanitized stack\",\n\t\t\t);\n\t\t});\n\t\tit(\"extract stack non-standard values\", () => {\n\t\t\t// sanitizeStack true\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties({ stack: \"hello\" }, true /* sanitizeStack */).stack,\n\t\t\t\t\"\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties(\n\t\t\t\t\t{ stack: \"hello\", name: \"name\" },\n\t\t\t\t\ttrue /* sanitizeStack */,\n\t\t\t\t).stack,\n\t\t\t\t\"name\",\n\t\t\t);\n\t\t\t// sanitizeStack false\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties({ stack: \"hello\" }, false /* sanitizeStack */).stack,\n\t\t\t\t\"hello\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties(\n\t\t\t\t\t{ stack: \"hello\", name: \"name\" },\n\t\t\t\t\tfalse /* sanitizeStack */,\n\t\t\t\t).stack,\n\t\t\t\t\"hello\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties({ foo: \"hello\" }, false /* sanitizeStack */).stack,\n\t\t\t\tundefined,\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties({ stack: 42 }, false /* sanitizeStack */).stack,\n\t\t\t\tundefined,\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties(42, false /* sanitizeStack */).stack,\n\t\t\t\tundefined,\n\t\t\t);\n\t\t});\n\t});\n\tdescribe(\"normalizeError\", () => {\n\t\tdescribe(\"preserves properties\", () => {\n\t\t\tit(\"missing properties are not set\", () => {\n\t\t\t\t// eslint-disable-next-line unicorn/error-message\n\t\t\t\tconst unknownError = new Error();\n\n\t\t\t\tconst newError: IFluidErrorBase & {\n\t\t\t\t\tcanRetry?: boolean;\n\t\t\t\t\tretryAfterSeconds?: number;\n\t\t\t\t} = normalizeError(unknownError);\n\n\t\t\t\tassert.strictEqual(newError.canRetry, undefined, \"canRetry not undefined\");\n\t\t\t\tassert.strictEqual(\n\t\t\t\t\tnewError.retryAfterSeconds,\n\t\t\t\t\tundefined,\n\t\t\t\t\t\"retryAfterSeconds not undefined\",\n\t\t\t\t);\n\t\t\t});\n\t\t\tit(\"existing retry properties are present in normalized error\", () => {\n\t\t\t\tconst unknownError: { canRetry?: boolean; retryAfterSeconds?: number } & Error =\n\t\t\t\t\t// eslint-disable-next-line unicorn/error-message\n\t\t\t\t\tnew Error();\n\t\t\t\tunknownError.canRetry = true;\n\t\t\t\tunknownError.retryAfterSeconds = 100;\n\n\t\t\t\tconst newError: IFluidErrorBase & {\n\t\t\t\t\tcanRetry?: boolean;\n\t\t\t\t\tretryAfterSeconds?: number;\n\t\t\t\t} = normalizeError(unknownError);\n\n\t\t\t\tassert.strictEqual(newError.canRetry, true, \"canRetry not true\");\n\t\t\t\tassert.strictEqual(newError.retryAfterSeconds, 100, \"retryAfterSeconds not 100\");\n\t\t\t});\n\t\t});\n\t});\n});\n\nclass TestFluidError implements IFluidErrorBase {\n\treadonly atpStub: sinon.SinonStub;\n\treadonly gtpSpy: sinon.SinonSpy;\n\texpectedTelemetryProps: ITelemetryBaseProperties;\n\n\treadonly errorType: string;\n\treadonly message: string;\n\treadonly stack?: string;\n\treadonly name: string = \"Error\";\n\treadonly errorInstanceId: string;\n\n\tconstructor(\n\t\terrorProps: Omit<\n\t\t\tIFluidErrorBase,\n\t\t\t\"getTelemetryProperties\" | \"addTelemetryProperties\" | \"errorInstanceId\" | \"name\"\n\t\t>,\n\t) {\n\t\tthis.errorType = errorProps.errorType;\n\t\tthis.message = errorProps.message;\n\t\tthis.stack = errorProps.stack;\n\t\tthis.errorInstanceId = uuid();\n\n\t\tthis.atpStub = sinon.stub(this, \"addTelemetryProperties\");\n\t\tthis.gtpSpy = sinon.spy(this, \"getTelemetryProperties\");\n\t\tthis.expectedTelemetryProps = { ...errorProps };\n\t}\n\n\tgetTelemetryProperties(): ITelemetryBaseProperties {\n\t\t// Don't actually return any props. We'll use the spy to ensure it was called\n\t\treturn {};\n\t}\n\n\taddTelemetryProperties(props: ITelemetryPropertiesExt): void {\n\t\tthrow new Error(\"Not Implemented - Expected to be Stubbed via Sinon\");\n\t}\n\n\twithoutProperty(propName: keyof IFluidErrorBase): this {\n\t\tconst objectWithoutProp = {};\n\t\tobjectWithoutProp[propName] = undefined;\n\t\tObject.assign(this, objectWithoutProp);\n\t\treturn this;\n\t}\n\n\twithExpectedTelemetryProps(props: ITelemetryBaseProperties): this {\n\t\tObject.assign(this.expectedTelemetryProps, props);\n\t\treturn this;\n\t}\n}\n\nconst annotationCases: Record<string, IFluidErrorAnnotations> = {\n\tnoAnnotations: {},\n\tjustProps: { props: { foo: \"bar\", one: 1, u: undefined, t: true } },\n};\n\ndescribe(\"normalizeError\", () => {\n\tdescribe(\"Valid Errors (Legacy and Current)\", () => {\n\t\tfor (const annotationCase of Object.keys(annotationCases)) {\n\t\t\tconst annotations = annotationCases[annotationCase];\n\t\t\tit(`Valid legacy error - Patch and return (annotations: ${annotationCase})`, () => {\n\t\t\t\t// Arrange\n\t\t\t\tconst errorProps = { errorType: \"et1\", message: \"m1\" };\n\t\t\t\tconst legacyError = new TestFluidError(errorProps).withoutProperty(\n\t\t\t\t\t\"errorInstanceId\",\n\t\t\t\t);\n\n\t\t\t\t// Act\n\t\t\t\tconst normalizedError = normalizeError(legacyError, annotations);\n\n\t\t\t\t// Assert\n\t\t\t\tassert.equal(\n\t\t\t\t\tnormalizedError,\n\t\t\t\t\tlegacyError,\n\t\t\t\t\t\"normalize should yield the same error as passed in\",\n\t\t\t\t);\n\t\t\t\tassert.equal(normalizedError.errorType, \"et1\", \"errorType should be unchanged\");\n\t\t\t\tassert.equal(normalizedError.message, \"m1\", \"message should be unchanged\");\n\t\t\t\tassert.equal(normalizedError.errorInstanceId.length, 36, \"should be guid-length\");\n\t\t\t\tif (annotations.props !== undefined) {\n\t\t\t\t\tassert(\n\t\t\t\t\t\tlegacyError.atpStub.calledWith(annotations.props),\n\t\t\t\t\t\t\"addTelemetryProperties should have been called\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t});\n\t\t\tit(`Valid Fluid Error - untouched (annotations: ${annotationCase})`, () => {\n\t\t\t\t// Arrange\n\t\t\t\tconst fluidError = new TestFluidError({ errorType: \"et1\", message: \"m1\" });\n\t\t\t\t// We don't expect legacyError to be modified itself at all\n\t\t\t\tObject.freeze(fluidError);\n\n\t\t\t\t// Act\n\t\t\t\tconst normalizedError = normalizeError(fluidError, annotations);\n\n\t\t\t\t// Assert\n\t\t\t\tassert(normalizedError === fluidError);\n\t\t\t\tif (annotations.props !== undefined) {\n\t\t\t\t\tassert(\n\t\t\t\t\t\tfluidError.atpStub.calledWith(annotations.props),\n\t\t\t\t\t\t\"addTelemetryProperties should have been called\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tit(\"Valid Fluid Error - stack not added if missing\", () => {\n\t\t\t// Arrange\n\t\t\tconst fluidError = new TestFluidError({\n\t\t\t\terrorType: \"et1\",\n\t\t\t\tmessage: \"m1\",\n\t\t\t}).withoutProperty(\"stack\");\n\t\t\t// We don't expect legacyError to be modified itself at all\n\t\t\tObject.freeze(fluidError);\n\n\t\t\t// Act\n\t\t\tconst normalizedError = normalizeError(fluidError, {});\n\n\t\t\t// Assert\n\t\t\tassert(normalizedError === fluidError);\n\t\t\tassert(normalizedError.stack === undefined);\n\t\t});\n\t\tit(\"Frozen legacy error - Throws\", () => {\n\t\t\t// Arrange\n\t\t\tconst errorProps = { errorType: \"et1\", message: \"m1\" };\n\t\t\tconst legacyError = new TestFluidError(errorProps).withoutProperty(\"errorInstanceId\");\n\t\t\tObject.freeze(legacyError);\n\n\t\t\t// Act/Assert\n\t\t\tassert.throws(\n\t\t\t\t() => normalizeError(legacyError, {}),\n\t\t\t\t/Cannot assign to read only property/,\n\t\t\t);\n\t\t});\n\t});\n\tdescribe(\"Errors Needing Normalization\", () => {\n\t\tclass NamedError extends Error {\n\t\t\tname = \"CoolErrorName\";\n\t\t}\n\t\tconst sampleFluidError = (): TestFluidError =>\n\t\t\tnew TestFluidError({\n\t\t\t\terrorType: \"someType\",\n\t\t\t\tmessage: \"Hello\",\n\t\t\t\tstack: \"cool stack trace\",\n\t\t\t});\n\t\tconst typicalOutput = (\n\t\t\tmessage: string,\n\t\t\tstackHint: \"<<natural stack>>\" | \"<<stack from input>>\",\n\t\t): TestFluidError =>\n\t\t\tnew TestFluidError({\n\t\t\t\terrorType: \"genericError\",\n\t\t\t\tmessage,\n\t\t\t\tstack: stackHint,\n\t\t\t});\n\t\tconst testCases: { [label: string]: () => { input: any; expectedOutput: TestFluidError } } =\n\t\t\t{\n\t\t\t\t\"Fluid Error minus errorType\": () => ({\n\t\t\t\t\tinput: sampleFluidError().withoutProperty(\"errorType\"),\n\t\t\t\t\texpectedOutput: typicalOutput(\"Hello\", \"<<stack from input>>\"),\n\t\t\t\t}),\n\t\t\t\t\"Fluid Error minus message\": () => ({\n\t\t\t\t\tinput: sampleFluidError().withoutProperty(\"message\"),\n\t\t\t\t\texpectedOutput: typicalOutput(\"[object Object]\", \"<<stack from input>>\"),\n\t\t\t\t}),\n\t\t\t\t\"Fluid Error minus getTelemetryProperties\": () => ({\n\t\t\t\t\tinput: sampleFluidError().withoutProperty(\"getTelemetryProperties\"),\n\t\t\t\t\texpectedOutput: typicalOutput(\"Hello\", \"<<stack from input>>\"),\n\t\t\t\t}),\n\t\t\t\t\"Fluid Error minus addTelemetryProperties\": () => ({\n\t\t\t\t\tinput: sampleFluidError().withoutProperty(\"addTelemetryProperties\"),\n\t\t\t\t\texpectedOutput: typicalOutput(\"Hello\", \"<<stack from input>>\"),\n\t\t\t\t}),\n\t\t\t\t\"Fluid Error minus errorType (no stack)\": () => ({\n\t\t\t\t\tinput: sampleFluidError().withoutProperty(\"errorType\").withoutProperty(\"stack\"),\n\t\t\t\t\texpectedOutput: typicalOutput(\"Hello\", \"<<natural stack>>\"),\n\t\t\t\t}),\n\t\t\t\t\"Fluid Error minus message (no stack)\": () => ({\n\t\t\t\t\tinput: sampleFluidError().withoutProperty(\"message\").withoutProperty(\"stack\"),\n\t\t\t\t\texpectedOutput: typicalOutput(\"[object Object]\", \"<<natural stack>>\"),\n\t\t\t\t}),\n\t\t\t\t\"Error object\": () => ({\n\t\t\t\t\tinput: new NamedError(\"boom\"),\n\t\t\t\t\texpectedOutput: typicalOutput(\n\t\t\t\t\t\t\"boom\",\n\t\t\t\t\t\t\"<<stack from input>>\",\n\t\t\t\t\t).withExpectedTelemetryProps({ untrustedOrigin: 1 }),\n\t\t\t\t}),\n\t\t\t\t\"LoggingError\": () => ({\n\t\t\t\t\tinput: new LoggingError(\"boom\"),\n\t\t\t\t\texpectedOutput: typicalOutput(\"boom\", \"<<stack from input>>\"),\n\t\t\t\t}),\n\t\t\t\t\"Empty object\": () => ({\n\t\t\t\t\tinput: {},\n\t\t\t\t\texpectedOutput: typicalOutput(\n\t\t\t\t\t\t\"[object Object]\",\n\t\t\t\t\t\t\"<<natural stack>>\",\n\t\t\t\t\t).withExpectedTelemetryProps({ untrustedOrigin: 1 }),\n\t\t\t\t}),\n\t\t\t\t\"object with stack\": () => ({\n\t\t\t\t\tinput: { message: \"whatever\", stack: \"fake stack goes here\" },\n\t\t\t\t\texpectedOutput: typicalOutput(\n\t\t\t\t\t\t\"whatever\",\n\t\t\t\t\t\t\"<<stack from input>>\",\n\t\t\t\t\t).withExpectedTelemetryProps({ untrustedOrigin: 1 }),\n\t\t\t\t}),\n\t\t\t\t\"object with non-string message and name\": () => ({\n\t\t\t\t\tinput: { message: 42, name: true },\n\t\t\t\t\texpectedOutput: typicalOutput(\n\t\t\t\t\t\t\"[object Object]\",\n\t\t\t\t\t\t\"<<natural stack>>\",\n\t\t\t\t\t).withExpectedTelemetryProps({ untrustedOrigin: 1 }),\n\t\t\t\t}),\n\t\t\t\t\"nullValue\": () => ({\n\t\t\t\t\tinput: null,\n\t\t\t\t\texpectedOutput: typicalOutput(\n\t\t\t\t\t\t\"null\",\n\t\t\t\t\t\t\"<<natural stack>>\",\n\t\t\t\t\t).withExpectedTelemetryProps({ untrustedOrigin: 1 }),\n\t\t\t\t}),\n\t\t\t\t\"undef\": () => ({\n\t\t\t\t\tinput: undefined,\n\t\t\t\t\texpectedOutput: typicalOutput(\n\t\t\t\t\t\t\"undefined\",\n\t\t\t\t\t\t\"<<natural stack>>\",\n\t\t\t\t\t).withExpectedTelemetryProps({ typeofError: \"undefined\", untrustedOrigin: 1 }),\n\t\t\t\t}),\n\t\t\t\t\"false\": () => ({\n\t\t\t\t\tinput: false,\n\t\t\t\t\texpectedOutput: typicalOutput(\n\t\t\t\t\t\t\"false\",\n\t\t\t\t\t\t\"<<natural stack>>\",\n\t\t\t\t\t).withExpectedTelemetryProps({ typeofError: \"boolean\", untrustedOrigin: 1 }),\n\t\t\t\t}),\n\t\t\t\t\"true\": () => ({\n\t\t\t\t\tinput: true,\n\t\t\t\t\texpectedOutput: typicalOutput(\n\t\t\t\t\t\t\"true\",\n\t\t\t\t\t\t\"<<natural stack>>\",\n\t\t\t\t\t).withExpectedTelemetryProps({ typeofError: \"boolean\", untrustedOrigin: 1 }),\n\t\t\t\t}),\n\t\t\t\t\"number\": () => ({\n\t\t\t\t\tinput: 3.14,\n\t\t\t\t\texpectedOutput: typicalOutput(\n\t\t\t\t\t\t\"3.14\",\n\t\t\t\t\t\t\"<<natural stack>>\",\n\t\t\t\t\t).withExpectedTelemetryProps({ typeofError: \"number\", untrustedOrigin: 1 }),\n\t\t\t\t}),\n\t\t\t\t\"symbol\": () => ({\n\t\t\t\t\tinput: Symbol(\"Unique\"),\n\t\t\t\t\texpectedOutput: typicalOutput(\n\t\t\t\t\t\t\"Symbol(Unique)\",\n\t\t\t\t\t\t\"<<natural stack>>\",\n\t\t\t\t\t).withExpectedTelemetryProps({ typeofError: \"symbol\", untrustedOrigin: 1 }),\n\t\t\t\t}),\n\t\t\t\t\"function\": () => ({\n\t\t\t\t\tinput: (): void => {},\n\t\t\t\t\texpectedOutput: typicalOutput(\n\t\t\t\t\t\t\"() => { }\",\n\t\t\t\t\t\t\"<<natural stack>>\",\n\t\t\t\t\t).withExpectedTelemetryProps({ typeofError: \"function\", untrustedOrigin: 1 }),\n\t\t\t\t}),\n\t\t\t\t\"emptyArray\": () => ({\n\t\t\t\t\tinput: [],\n\t\t\t\t\texpectedOutput: typicalOutput(\n\t\t\t\t\t\t\"\",\n\t\t\t\t\t\t\"<<natural stack>>\",\n\t\t\t\t\t).withExpectedTelemetryProps({ untrustedOrigin: 1 }),\n\t\t\t\t}),\n\t\t\t\t\"array\": () => ({\n\t\t\t\t\tinput: [1, 2, 3],\n\t\t\t\t\texpectedOutput: typicalOutput(\n\t\t\t\t\t\t\"1,2,3\",\n\t\t\t\t\t\t\"<<natural stack>>\",\n\t\t\t\t\t).withExpectedTelemetryProps({ untrustedOrigin: 1 }),\n\t\t\t\t}),\n\t\t\t};\n\t\tfunction assertMatching(\n\t\t\tactual: IFluidErrorBase,\n\t\t\texpected: TestFluidError,\n\t\t\tannotations: IFluidErrorAnnotations = {},\n\t\t\tinputStack: string | undefined,\n\t\t): void {\n\t\t\texpected.withExpectedTelemetryProps({\n\t\t\t\t...annotations.props,\n\t\t\t\terrorInstanceId: actual.errorInstanceId,\n\t\t\t\tfluidErrorCode: \"-\", // Present for back-compat\n\t\t\t});\n\n\t\t\tassertMatchingMessageAndStack(actual, expected, inputStack);\n\n\t\t\tassert.equal(actual.errorType, expected.errorType, \"errorType should match\");\n\t\t\tassert.equal(actual.name, expected.name, \"name should match\");\n\t\t\tassert.equal(actual.errorInstanceId.length, 36, \"should be guid-length\");\n\t\t\tassert.deepStrictEqual(\n\t\t\t\tactual.getTelemetryProperties(),\n\t\t\t\texpected.expectedTelemetryProps,\n\t\t\t\t\"telemetry props should match\",\n\t\t\t);\n\t\t}\n\t\tfunction assertMatchingMessageAndStack(\n\t\t\tactual: IFluidErrorBase,\n\t\t\texpected: TestFluidError,\n\t\t\tinputStack: string | undefined,\n\t\t): void {\n\t\t\tassert.equal(actual.message, expected.message, \"message should match\");\n\t\t\tconst actualStack = actual.stack;\n\t\t\tassert(actualStack !== undefined, \"stack should be present as a string\");\n\t\t\tif (actualStack.includes(\"at normalizeError\")) {\n\t\t\t\t// This indicates the stack was populated naturally by new SimpleFluidError\n\t\t\t\tassert.equal(\n\t\t\t\t\texpected.stack,\n\t\t\t\t\t\"<<natural stack>>\",\n\t\t\t\t\t\"<<natural stack>> hint should be used if not overwritten\",\n\t\t\t\t);\n\t\t\t\texpected.withExpectedTelemetryProps({ stack: actualStack });\n\t\t\t} else {\n\t\t\t\tassert.equal(\n\t\t\t\t\tactualStack,\n\t\t\t\t\tinputStack,\n\t\t\t\t\t\"If stack wasn't generated, it should match input stack\",\n\t\t\t\t);\n\t\t\t\tassert.equal(\n\t\t\t\t\texpected.stack,\n\t\t\t\t\t\"<<stack from input>>\",\n\t\t\t\t\t\"<<stack from input>> hint should be used if using stack from input error object\",\n\t\t\t\t);\n\t\t\t\texpected.withExpectedTelemetryProps({ stack: inputStack });\n\t\t\t}\n\t\t}\n\t\tfor (const annotationCase of Object.keys(annotationCases)) {\n\t\t\tconst annotations = annotationCases[annotationCase];\n\t\t\tlet doneOnceForThisAnnotationCase = false;\n\t\t\tfor (const caseName of Object.keys(testCases)) {\n\t\t\t\tconst getTestCase = testCases[caseName];\n\t\t\t\tif (!doneOnceForThisAnnotationCase) {\n\t\t\t\t\tdoneOnceForThisAnnotationCase = true;\n\t\t\t\t\t// Each test case only differs by what stack/error are. Test the rest only once per annotation case.\n\t\t\t\t\tit(`Normalize untrusted error full validation: (${annotationCase})`, () => {\n\t\t\t\t\t\t// Arrange\n\t\t\t\t\t\tconst { input, expectedOutput } = getTestCase();\n\n\t\t\t\t\t\t// Act\n\t\t\t\t\t\tconst normalized = normalizeError(input, annotations);\n\n\t\t\t\t\t\t// Assert\n\t\t\t\t\t\tassert.notEqual(\n\t\t\t\t\t\t\tinput,\n\t\t\t\t\t\t\tnormalized,\n\t\t\t\t\t\t\t\"input should have yielded a new error object\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\tassertMatching(normalized, expectedOutput, annotations, input?.stack);\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tinput instanceof TestFluidError &&\n\t\t\t\t\t\t\tinput.getTelemetryProperties !== undefined\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tassert(\n\t\t\t\t\t\t\t\tinput.gtpSpy.calledOnce,\n\t\t\t\t\t\t\t\t\"input.getTelemetryProperties should have been called by normalizeError\",\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Bonus\n\t\t\t\t\t\tnormalized.addTelemetryProperties({ foo: \"bar\" });\n\t\t\t\t\t\tassert.equal(\n\t\t\t\t\t\t\tnormalized.getTelemetryProperties().foo,\n\t\t\t\t\t\t\t\"bar\",\n\t\t\t\t\t\t\t\"can add telemetry props after normalization\",\n\t\t\t\t\t\t);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tit(`Normalize untrusted error message/stack: ${caseName} (${annotationCase})`, () => {\n\t\t\t\t\t// Arrange\n\t\t\t\t\tconst { input, expectedOutput } = getTestCase();\n\n\t\t\t\t\t// Act\n\t\t\t\t\tconst normalized = normalizeError(input, annotations);\n\n\t\t\t\t\t// Assert\n\t\t\t\t\tassert.notEqual(\n\t\t\t\t\t\tinput,\n\t\t\t\t\t\tnormalized,\n\t\t\t\t\t\t\"input should have yielded a new error object\",\n\t\t\t\t\t);\n\t\t\t\t\tassertMatchingMessageAndStack(normalized, expectedOutput, input?.stack);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t});\n});\n\n/**\n * Create an error missing errorType that will not be recognized as a valid Fluid error\n */\nconst createExternalError = (m: string): Error => new Error(m);\n\n/**\n * Create a simple valid Fluid error\n */\nconst createTestError = (\n\tm: string,\n): LoggingError & {\n\terrorType: string;\n} =>\n\tObject.assign(new LoggingError(m), {\n\t\terrorType: \"someErrorType\",\n\t});\n\ndescribe(\"wrapError\", () => {\n\tit(\"Copy message, stack, and props\", () => {\n\t\tconst innerError = new LoggingError(\"hello\", { someProp: 123 });\n\t\tinnerError.stack = \"extra special stack\";\n\t\tconst newError = wrapError(innerError, createTestError);\n\t\tassert.equal(newError.message, innerError.message, \"messages should match\");\n\t\tassert.equal(newError.stack, innerError.stack, \"stacks should match\");\n\t\tassert.equal(newError.getTelemetryProperties().someProp, 123, \"Props should be preserved\");\n\t});\n\tit(\"Include matching errorInstanceId and innerErrorInstanceId in telemetry props\", () => {\n\t\tconst innerError = new LoggingError(\"hello\");\n\t\tconst newError = wrapError(innerError, createTestError);\n\t\tassert(newError.errorInstanceId === innerError.errorInstanceId);\n\t\tassert(\n\t\t\tnewError.getTelemetryProperties().innerErrorInstanceId === innerError.errorInstanceId,\n\t\t);\n\t});\n\tit(\"Properly set untrustedOrigin\", () => {\n\t\tconst untrustedError = createExternalError(\"untrusted\");\n\n\t\tconst singleWrapped = wrapError(untrustedError, createTestError);\n\t\tassert(\n\t\t\tsingleWrapped.getTelemetryProperties().untrustedOrigin === 1,\n\t\t\t\"wrapped external error should be 'untrustedOrigin'\",\n\t\t);\n\n\t\tconst doubleWrapped = wrapError(singleWrapped, createTestError);\n\t\tassert(\n\t\t\tdoubleWrapped.getTelemetryProperties().untrustedOrigin === 1,\n\t\t\t\"doubly-wrapped external error should be 'untrustedOrigin'\",\n\t\t);\n\n\t\tconst normalizedError = normalizeError(untrustedError);\n\t\tconst wrappedNormalized = wrapError(normalizedError, createTestError);\n\t\tassert(\n\t\t\twrappedNormalized.getTelemetryProperties().untrustedOrigin === 1,\n\t\t\t\"normalized-then-wrapped external error should be 'untrustedOrigin'\",\n\t\t);\n\n\t\tconst trustedError = createTestError(\"trusted\");\n\t\tconst wrappedTrusted = wrapError(trustedError, createTestError);\n\t\tassert(\n\t\t\twrappedTrusted.getTelemetryProperties().untrustedOrigin === undefined,\n\t\t\t\"wrapped Fluid error should not be 'untrustedOrigin'\",\n\t\t);\n\t});\n});\ndescribe(\"wrapErrorAndLog\", () => {\n\tconst mockLogger = new MockLogger();\n\tconst innerError = new LoggingError(\"hello\");\n\tconst newError = wrapErrorAndLog(innerError, createTestError, mockLogger.toTelemetryLogger());\n\tassert(\n\t\tmockLogger.matchEvents([\n\t\t\t{\n\t\t\t\teventName: \"WrapError\",\n\t\t\t\twrappedByErrorInstanceId: newError.errorInstanceId,\n\t\t\t\terrorInstanceId: newError.errorInstanceId,\n\t\t\t\terror: \"hello\",\n\t\t\t},\n\t\t]),\n\t\t\"Expected the 'WrapError' event to be logged\",\n\t);\n});\n\ndescribe(\"Error Discovery\", () => {\n\tit(\"isExternalError\", () => {\n\t\tassert(isExternalError(\"some string\"));\n\t\tassert(isExternalError(createExternalError(\"error message\")));\n\t\tassert(isExternalError(normalizeError(\"normalize me but I'm still external\")));\n\t\tassert(\n\t\t\tisExternalError(\n\t\t\t\tnormalizeError(createExternalError(\"normalize me but I'm still external\")),\n\t\t\t),\n\t\t);\n\n\t\tassert(!isExternalError(createTestError(\"hello\")));\n\n\t\tconst wrappedError = wrapError(\"wrap me\", createTestError);\n\t\tassert(!isExternalError(wrappedError));\n\t\tassert(wrappedError.getTelemetryProperties().untrustedOrigin === 1); // But it should still say untrustedOrigin\n\t\tassert(!isExternalError(new LoggingError(\"testLoggingError\")));\n\t});\n\tit(\"isValidLegacyError\", () => {\n\t\tconst validLegacyError = {\n\t\t\tmessage: \"testMessage\",\n\t\t\terrorType: \"someErrorType\",\n\t\t\tgetTelemetryProperties: (): void => {},\n\t\t\taddTelemetryProperties: (): void => {},\n\t\t};\n\t\tassert.strictEqual(isValidLegacyError(validLegacyError), true);\n\t\tassert.strictEqual(isValidLegacyError({ ...validLegacyError, message: undefined }), false);\n\t\tassert.strictEqual(\n\t\t\tisValidLegacyError({ ...validLegacyError, errorType: undefined }),\n\t\t\tfalse,\n\t\t);\n\t\tassert.strictEqual(\n\t\t\tisValidLegacyError({ ...validLegacyError, getTelemetryProperties: undefined }),\n\t\t\tfalse,\n\t\t);\n\t\tassert.strictEqual(\n\t\t\tisValidLegacyError({ ...validLegacyError, addTelemetryProperties: undefined }),\n\t\t\tfalse,\n\t\t);\n\t});\n\n\t// I copied the old version of isFluidError here, it depends on fluidErrorCode.\n\t// I want to make sure that an error built on LoggingError that otherwise matches isFluidError\n\t// will match isFluidError in old code (e.g. when an error flows across layers)\n\tfunction isFluidError_old(e: any): e is IFluidErrorBase {\n\t\tconst hasTelemetryPropFunctions = (x: any): boolean =>\n\t\t\ttypeof x?.getTelemetryProperties === \"function\" &&\n\t\t\ttypeof x?.addTelemetryProperties === \"function\";\n\t\treturn (\n\t\t\ttypeof e?.errorType === \"string\" &&\n\t\t\ttypeof e?.fluidErrorCode === \"string\" &&\n\t\t\ttypeof e?.message === \"string\" &&\n\t\t\thasErrorInstanceId(e) &&\n\t\t\thasTelemetryPropFunctions(e)\n\t\t);\n\t}\n\n\tfunction testFluidError(isFluidErrorImpl: (e: any) => boolean, isOld: boolean): void {\n\t\tit(`isFluidError${isOld ? \"_old\" : \"\"}`, () => {\n\t\t\tassert(\n\t\t\t\t!isFluidErrorImpl(new Error(\"hello\")),\n\t\t\t\t\"Plain Error object is not a Fluid Error\",\n\t\t\t);\n\t\t\tassert(\n\t\t\t\t!isFluidErrorImpl(new LoggingError(\"hello\")),\n\t\t\t\t\"LoggingError is not a Fluid Error (no errorType)\",\n\t\t\t);\n\t\t\tassert(\n\t\t\t\t!isFluidErrorImpl(\n\t\t\t\t\tObject.assign(new Error(\"hello\"), {\n\t\t\t\t\t\terrorType: \"someErrorType\",\n\t\t\t\t\t\t_errorInstanceId: \"12345\",\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t\t\"Error with errorType and errorInstanceId but without telemetry prop fns is not a Fluid Error\",\n\t\t\t);\n\t\t\tassert(\n\t\t\t\t!isFluidErrorImpl(createExternalError(\"hello\")),\n\t\t\t\t\"Error without errorType is not a Fluid Error\",\n\t\t\t);\n\t\t\tassert(\n\t\t\t\t!isFluidErrorImpl(\n\t\t\t\t\tObject.assign(createTestError(\"hello\"), { _errorInstanceId: undefined }),\n\t\t\t\t),\n\t\t\t\t\"Valid Fluid Error with errorInstanceId removed is not a Fluid Error\",\n\t\t\t);\n\t\t\tassert(\n\t\t\t\tisFluidErrorImpl(createTestError(\"hello\")),\n\t\t\t\t\"Valid Fluid Error is a Fluid Error\",\n\t\t\t);\n\t\t\tassert.equal(\n\t\t\t\t!isOld,\n\t\t\t\tisFluidErrorImpl(\n\t\t\t\t\tObject.assign(createTestError(\"hello\"), { fluidErrorCode: undefined }),\n\t\t\t\t),\n\t\t\t\t\"Old isFluidError impl should require fluidErrorCode but New should not\",\n\t\t\t);\n\t\t});\n\t}\n\ttestFluidError(isFluidError, false /* isOld */);\n\ttestFluidError(isFluidError_old, true /* isOld */);\n});\n"]}
|
|
1
|
+
{"version":3,"file":"errorLogging.spec.js","sourceRoot":"","sources":["../../src/test/errorLogging.spec.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\n/* eslint-disable @typescript-eslint/no-unsafe-member-access */\n/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable @typescript-eslint/no-unsafe-argument */\n/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n/* eslint-disable @typescript-eslint/no-unsafe-call */\n/* eslint-disable unicorn/consistent-function-scoping */\n/* eslint-disable unicorn/no-null */\n\nimport { strict as assert } from \"node:assert\";\nimport type {\n\tITelemetryBaseEvent,\n\tITelemetryBaseProperties,\n} from \"@fluidframework/core-interfaces\";\nimport sinon from \"sinon\";\nimport { v4 as uuid } from \"uuid\";\nimport {\n\tIFluidErrorAnnotations,\n\tLoggingError,\n\textractLogSafeErrorProperties,\n\tisExternalError,\n\tisTaggedTelemetryPropertyValue,\n\tnormalizeError,\n\twrapError,\n\twrapErrorAndLog,\n} from \"../errorLogging.js\";\nimport {\n\tIFluidErrorBase,\n\thasErrorInstanceId,\n\tisFluidError,\n\tisValidLegacyError,\n} from \"../fluidErrorBase.js\";\nimport { TaggedLoggerAdapter, TelemetryDataTag, TelemetryLogger } from \"../logger.js\";\nimport { MockLogger } from \"../mockLogger.js\";\nimport type { ITelemetryPropertiesExt } from \"../telemetryTypes.js\";\n\ndescribe(\"Error Logging\", () => {\n\tdescribe(\"TelemetryLogger.prepareErrorObject\", () => {\n\t\tfunction freshEvent(): ITelemetryBaseEvent {\n\t\t\treturn { category: \"cat1\", eventName: \"event1\" };\n\t\t}\n\t\tfunction createILoggingError(props: ITelemetryBaseProperties): {\n\t\t\tgetTelemetryProperties: () => ITelemetryBaseProperties;\n\t\t} {\n\t\t\treturn { ...props, getTelemetryProperties: (): ITelemetryBaseProperties => props };\n\t\t}\n\n\t\tit(\"non-object error added to event\", () => {\n\t\t\tlet event = freshEvent();\n\t\t\tTelemetryLogger.prepareErrorObject(event, \"hello\", false);\n\t\t\tassert.strictEqual(event.error, \"hello\", \"string should work\");\n\t\t\tevent = freshEvent();\n\t\t\tTelemetryLogger.prepareErrorObject(event, 42, false);\n\t\t\tassert.strictEqual(event.error, \"42\", \"number should work\");\n\t\t\tevent = freshEvent();\n\t\t\tTelemetryLogger.prepareErrorObject(event, true, false);\n\t\t\tassert.strictEqual(event.error, \"true\", \"boolean should work\");\n\t\t\tevent = freshEvent();\n\t\t\tTelemetryLogger.prepareErrorObject(event, undefined, false);\n\t\t\tassert.strictEqual(event.error, \"undefined\", \"undefined should work\");\n\n\t\t\t// Technically this violates TelemetryBaseEventPropertyType's type constraint but it's actually supported\n\t\t\tevent = freshEvent();\n\t\t\tTelemetryLogger.prepareErrorObject(event, null, false);\n\t\t\tassert.strictEqual(event.error, \"null\", \"null should work\");\n\t\t});\n\t\tit(\"stack and message added to event (stack should exclude message)\", () => {\n\t\t\tconst event = freshEvent();\n\t\t\tconst error = new Error(\"boom\");\n\t\t\terror.name = \"MyErrorName\";\n\t\t\tTelemetryLogger.prepareErrorObject(event, error, false);\n\t\t\tassert(event.error === \"boom\");\n\t\t\tassert((event.stack as string).includes(\"MyErrorName\"));\n\t\t\tassert(!(event.stack as string).includes(\"boom\"));\n\t\t});\n\t\tit(\"containsPII (legacy) is ignored\", () => {\n\t\t\t// Previously, setting containsPII = true on an error obj would (attempt to) redact its message\n\t\t\tconst event = freshEvent();\n\t\t\tconst error = new Error(\"boom\");\n\t\t\terror.name = \"MyErrorName\";\n\t\t\t(error as any).containsPII = true;\n\t\t\tTelemetryLogger.prepareErrorObject(event, error, false);\n\t\t\tassert(event.error === \"boom\");\n\t\t\tassert((event.stack as string).includes(\"MyErrorName\"));\n\t\t});\n\t\tit(\"getTelemetryProperties - tags on overwritten Error base props\", () => {\n\t\t\tconst event = freshEvent();\n\t\t\tconst error = createILoggingError({\n\t\t\t\tmessage: { value: \"Mark Fields\", tag: \"UserData\" }, // hopefully no one does this!\n\t\t\t\tstack: { value: \"tagged\", tag: TelemetryDataTag.CodeArtifact },\n\t\t\t});\n\t\t\tTelemetryLogger.prepareErrorObject(event, error, false);\n\t\t\tassert.deepStrictEqual(event.message, { value: \"Mark Fields\", tag: \"UserData\" });\n\t\t\tassert.deepStrictEqual(event.error, \"[object Object]\"); // weird but ok\n\t\t\tassert.deepStrictEqual(event.stack, {\n\t\t\t\tvalue: \"tagged\",\n\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t});\n\t\t});\n\t\tit(\"getTelemetryProperties absent - no further props added\", () => {\n\t\t\tconst event = freshEvent();\n\t\t\tconst error = { ...new Error(\"boom\"), foo: \"foo\", bar: 2 };\n\t\t\tTelemetryLogger.prepareErrorObject(event, error, false);\n\t\t\tassert(event.foo === undefined && event.bar === undefined);\n\t\t});\n\t\tit(\"getTelemetryProperties overlaps event - do not overwrite\", () => {\n\t\t\tconst event = { ...freshEvent(), foo: \"event_foo\", bar: 42 };\n\t\t\tconst error = createILoggingError({ foo: \"error_foo\", bar: -1 });\n\t\t\tTelemetryLogger.prepareErrorObject(event, error, false);\n\t\t\tassert(event.foo === \"event_foo\" && event.bar === 42);\n\t\t});\n\t\tit(\"getTelemetryProperties present - add additional props\", () => {\n\t\t\tconst event = freshEvent();\n\t\t\tconst error = createILoggingError({ foo: \"foo\", bar: 2 });\n\t\t\tTelemetryLogger.prepareErrorObject(event, error, false);\n\t\t\tassert(event.foo === \"foo\" && event.bar === 2);\n\t\t});\n\t\tit(\"fetchStack false - Don't add a stack if missing\", () => {\n\t\t\tconst event = freshEvent();\n\t\t\tconst error = { message: \"I have no stack\" };\n\t\t\tTelemetryLogger.prepareErrorObject(event, error, false);\n\t\t\tassert.strictEqual(event.stack, undefined);\n\t\t});\n\t\tit(\"fetchStack true - Don't add a stack if present\", () => {\n\t\t\tconst event = freshEvent();\n\t\t\tconst error = new Error(\"boom\");\n\t\t\terror.name = \"MyName\";\n\t\t\tTelemetryLogger.prepareErrorObject(event, error, false);\n\t\t\tassert((event.stack as string).includes(\"MyName\"));\n\t\t});\n\t\tit(\"fetchStack true - Add a stack if missing\", () => {\n\t\t\tconst event = freshEvent();\n\t\t\tconst error = { message: \"I have no stack - boom\", name: \"MyName\" };\n\t\t\tTelemetryLogger.prepareErrorObject(event, error, true);\n\t\t\tassert.strictEqual(typeof event.stack, \"string\");\n\t\t\tassert(!(event.stack as string).includes(\"MyName\"));\n\t\t});\n\t});\n\tdescribe(\"TaggedLoggerAdapter\", () => {\n\t\tconst events: ITelemetryBaseEvent[] = [];\n\t\tclass TestTelemetryLogger extends TelemetryLogger {\n\t\t\tpublic events: ITelemetryBaseEvent[] = [];\n\t\t\tpublic send(event: ITelemetryBaseEvent): void {\n\t\t\t\tevents.push(this.prepareEvent(event));\n\t\t\t}\n\t\t}\n\t\tconst adaptedLogger = new TaggedLoggerAdapter(new TestTelemetryLogger(\"namespace\"));\n\n\t\tit(\"TaggedLoggerAdapter - tagged UserData is removed\", () => {\n\t\t\tconst event = {\n\t\t\t\tcategory: \"cat\",\n\t\t\t\teventName: \"event\",\n\t\t\t\tuserDataObject: {\n\t\t\t\t\ttag: TelemetryDataTag.UserData,\n\t\t\t\t\tvalue: \"someUserData\",\n\t\t\t\t},\n\t\t\t};\n\t\t\tadaptedLogger.send(event);\n\t\t\tassert.strictEqual(\n\t\t\t\tevents[0].userDataObject,\n\t\t\t\t\"REDACTED (UserData)\",\n\t\t\t\t\"someUserData should be redacted\",\n\t\t\t);\n\t\t\tevents.pop();\n\t\t});\n\t\tit(\"TaggedLoggerAdapter - tagged CodeArtifact are preserved\", () => {\n\t\t\tconst event = {\n\t\t\t\tcategory: \"cat\",\n\t\t\t\teventName: \"event\",\n\t\t\t\tpackageDataObject: {\n\t\t\t\t\ttag: TelemetryDataTag.CodeArtifact,\n\t\t\t\t\tvalue: \"somePackageData\",\n\t\t\t\t},\n\t\t\t};\n\t\t\tadaptedLogger.send(event);\n\t\t\tassert.strictEqual(\n\t\t\t\tevents[0].packageDataObject,\n\t\t\t\t\"somePackageData\",\n\t\t\t\t\"somePackageData should be preserved\",\n\t\t\t);\n\t\t\tevents.pop();\n\t\t});\n\t\tit(\"TaggedLoggerAdapter - tagged [unrecognized tag] are removed\", () => {\n\t\t\tconst event = {\n\t\t\t\tcategory: \"cat\",\n\t\t\t\teventName: \"event\",\n\t\t\t\tunknownTaggedObject: {\n\t\t\t\t\ttag: \"someUnknownTag\",\n\t\t\t\t\tvalue: \"someEvilData\",\n\t\t\t\t},\n\t\t\t};\n\t\t\tadaptedLogger.send(event);\n\t\t\tassert.strictEqual(\n\t\t\t\tevents[0].unknownTaggedObject,\n\t\t\t\t\"REDACTED (unknown tag)\",\n\t\t\t\t\"someUnknownTag should be redacted\",\n\t\t\t);\n\t\t\tevents.pop();\n\t\t});\n\t});\n\tdescribe(\"TaggedTelemetryData\", () => {\n\t\tit(\"Ensure backwards compatibility\", () => {\n\t\t\t// The values of the enum should never change (even if the keys are renamed)\n\t\t\tassert(TelemetryDataTag.CodeArtifact === (\"CodeArtifact\" as TelemetryDataTag));\n\t\t\tassert(TelemetryDataTag.UserData === (\"UserData\" as TelemetryDataTag));\n\t\t});\n\t});\n\tdescribe(\"isTaggedTelemetryPropertyValue\", () => {\n\t\tit(\"non-object input not ok\", () => {\n\t\t\tassert.strictEqual(isTaggedTelemetryPropertyValue(\"hello\"), false);\n\t\t\tassert.strictEqual(isTaggedTelemetryPropertyValue(123), false);\n\t\t\tassert.strictEqual(isTaggedTelemetryPropertyValue(false), false);\n\t\t\tassert.strictEqual(isTaggedTelemetryPropertyValue(undefined), false);\n\t\t\tassert.strictEqual(isTaggedTelemetryPropertyValue(null as any), false);\n\t\t\tassert.strictEqual(\n\t\t\t\tisTaggedTelemetryPropertyValue(function x() {\n\t\t\t\t\treturn 54;\n\t\t\t\t} as any),\n\t\t\t\tfalse,\n\t\t\t);\n\t\t\tassert.strictEqual(isTaggedTelemetryPropertyValue(Symbol(\"okay\") as any), false);\n\t\t});\n\t\tit(\"non-object value ok\", () => {\n\t\t\tassert.strictEqual(\n\t\t\t\tisTaggedTelemetryPropertyValue({ value: \"hello\", tag: \"any string\" }),\n\t\t\t\ttrue,\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\tisTaggedTelemetryPropertyValue({ value: 123, tag: \"any string\" }),\n\t\t\t\ttrue,\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\tisTaggedTelemetryPropertyValue({ value: false, tag: \"any string\" }),\n\t\t\t\ttrue,\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\tisTaggedTelemetryPropertyValue({ value: undefined, tag: \"any string\" }),\n\t\t\t\ttrue,\n\t\t\t);\n\t\t});\n\t\tit(\"Check result for various invalid inputs (per typings)\", () => {\n\t\t\tassert.strictEqual(\n\t\t\t\tisTaggedTelemetryPropertyValue({ tag: \"any string\" } as any),\n\t\t\t\ttrue,\n\t\t\t\t\"value prop may be absent\",\n\t\t\t);\n\t\t\t// The type guard used is a bit imprecise. Here is proof (these \"shouldn't\" be ok)\n\t\t\tassert.strictEqual(\n\t\t\t\tisTaggedTelemetryPropertyValue({\n\t\t\t\t\tvalue: function x() {\n\t\t\t\t\t\treturn 54;\n\t\t\t\t\t} as any,\n\t\t\t\t\ttag: \"any string\",\n\t\t\t\t}),\n\t\t\t\ttrue,\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\tisTaggedTelemetryPropertyValue({ value: Symbol(\"okay\") as any, tag: \"any string\" }),\n\t\t\t\ttrue,\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\tisTaggedTelemetryPropertyValue({ value: \"hello\", tag: 1 } as any),\n\t\t\t\tfalse,\n\t\t\t\t\"number tag is bad\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\tisTaggedTelemetryPropertyValue({ value: \"hello\", tag: false } as any),\n\t\t\t\tfalse,\n\t\t\t\t\"boolean tag is bad\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\tisTaggedTelemetryPropertyValue({ value: \"hello\", tag: {} } as any),\n\t\t\t\tfalse,\n\t\t\t\t\"object tag is bad\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\tisTaggedTelemetryPropertyValue({ value: \"hello\", tag: null } as any),\n\t\t\t\tfalse,\n\t\t\t\t\"null tag is bad\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\tisTaggedTelemetryPropertyValue({ value: \"hello\" } as any),\n\t\t\t\tfalse,\n\t\t\t\t\"undefined (missing) tag is bad\",\n\t\t\t);\n\t\t});\n\t});\n\tdescribe(\"LoggingError\", () => {\n\t\tit(\"ctor props are assigned to the object\", () => {\n\t\t\tconst loggingError = new LoggingError(\"myMessage\", {\n\t\t\t\tp1: 1,\n\t\t\t\tp2: \"two\",\n\t\t\t\tp3: true,\n\t\t\t\ttagged: { value: 4, tag: \"CodeArtifact\" },\n\t\t\t});\n\t\t\tconst errorAsAny = loggingError as any;\n\t\t\tassert.strictEqual(errorAsAny.message, \"myMessage\");\n\t\t\tassert.strictEqual(errorAsAny.p1, 1);\n\t\t\tassert.strictEqual(errorAsAny.p2, \"two\");\n\t\t\tassert.strictEqual(errorAsAny.p3, true);\n\t\t\tassert.deepStrictEqual(errorAsAny.tagged, { value: 4, tag: \"CodeArtifact\" });\n\t\t});\n\t\tit(\"errorInstanceId unique each time\", () => {\n\t\t\tconst e1 = new LoggingError(\"1\");\n\t\t\tconst e2 = new LoggingError(\"2\");\n\t\t\tassert.equal(e1.errorInstanceId.length, 36, \"should be guid-length\");\n\t\t\tassert.equal(e2.errorInstanceId.length, 36, \"should be guid-length\");\n\t\t\tassert.notEqual(\n\t\t\t\te1.errorInstanceId,\n\t\t\t\te2.errorInstanceId,\n\t\t\t\t\"each error instance should get unique id\",\n\t\t\t);\n\t\t});\n\t\tit(\"getTelemetryProperties extracts all untagged ctor props\", () => {\n\t\t\tconst loggingError = new LoggingError(\"myMessage\", { p1: 1, p2: \"two\", p3: true });\n\t\t\tconst props = loggingError.getTelemetryProperties();\n\t\t\tassert.strictEqual(props.message, \"myMessage\");\n\t\t\tassert.strictEqual(typeof props.stack, \"string\");\n\t\t\tassert.strictEqual(props.name, undefined); // Error.name is not logged\n\t\t\tassert.strictEqual(props.p1, 1);\n\t\t\tassert.strictEqual(props.p2, \"two\");\n\t\t\tassert.strictEqual(props.p3, true);\n\t\t});\n\t\tit(\"getTelemetryProperties respects omitPropsFromLogging\", () => {\n\t\t\tconst loggingError = new LoggingError(\"myMessage\", {}, new Set([\"foo\"]));\n\t\t\t(loggingError as any).foo = \"secrets!\";\n\t\t\t(loggingError as any).bar = \"normal\";\n\t\t\tconst props = loggingError.getTelemetryProperties();\n\t\t\tassert.strictEqual(\n\t\t\t\tprops.omitPropsFromLogging,\n\t\t\t\tundefined,\n\t\t\t\t\"omitPropsFromLogging itself should be omitted\",\n\t\t\t);\n\t\t\tassert.strictEqual(props.foo, undefined, \"foo should have been omitted\");\n\t\t\tassert.strictEqual(props.bar, \"normal\", \"bar should not be omitted\");\n\t\t});\n\t\tit(\"addTelemetryProperties - adds to object, returned from getTelemetryProperties, doesn't overwrite\", () => {\n\t\t\tconst loggingError = new LoggingError(\"myMessage\", { p1: 1, p2: \"two\", p3: true });\n\t\t\t(loggingError as any).p1 = \"should not be overwritten\";\n\t\t\tloggingError.addTelemetryProperties({\n\t\t\t\tp1: \"ignored\",\n\t\t\t\tp4: 4,\n\t\t\t\tp5: true,\n\t\t\t\tp6: { value: 5, tag: \"CodeArtifact\" },\n\t\t\t\tp7: [\"a\", \"b\", \"c\"],\n\t\t\t\tp8: [1, 2, 3],\n\t\t\t\tp9: [true, true, false],\n\t\t\t\tp10: { one: \"1\" },\n\t\t\t\tp11: undefined,\n\t\t\t\tp12: { value: [\"1\", 2, true], tag: \"CodeArtifact\" },\n\t\t\t});\n\t\t\tconst props = loggingError.getTelemetryProperties();\n\t\t\tassert.strictEqual(props.p1, \"should not be overwritten\");\n\t\t\tassert.strictEqual(props.p4, 4);\n\t\t\tassert.strictEqual(props.p5, true);\n\t\t\tassert.deepStrictEqual(props.p6, { value: 5, tag: \"CodeArtifact\" });\n\t\t\tassert.strictEqual(props.p7, '[\"a\",\"b\",\"c\"]');\n\t\t\tassert.strictEqual(props.p8, \"[1,2,3]\");\n\t\t\tassert.strictEqual(props.p9, \"[true,true,false]\");\n\t\t\tassert.strictEqual(props.p10, `{\"one\":\"1\"}`);\n\t\t\tassert.strictEqual(props.p11, undefined);\n\t\t\tassert.deepStrictEqual(props.p12, { value: `[\"1\",2,true]`, tag: \"CodeArtifact\" });\n\t\t\tconst errorAsAny = loggingError as any;\n\t\t\tassert.strictEqual(errorAsAny.p1, \"should not be overwritten\");\n\t\t\tassert.strictEqual(errorAsAny.p4, 4);\n\t\t\tassert.strictEqual(errorAsAny.p5, true);\n\t\t\tassert.deepStrictEqual(errorAsAny.p6, { value: 5, tag: \"CodeArtifact\" });\n\t\t\tassert.deepStrictEqual(errorAsAny.p7, [\"a\", \"b\", \"c\"]);\n\t\t\tassert.deepStrictEqual(errorAsAny.p8, [1, 2, 3]);\n\t\t\tassert.deepStrictEqual(errorAsAny.p9, [true, true, false]);\n\t\t\tassert.deepStrictEqual(errorAsAny.p10, { one: \"1\" });\n\t\t\tassert.strictEqual(errorAsAny.p11, undefined);\n\t\t\tassert.deepStrictEqual(errorAsAny.p12, { value: [\"1\", 2, true], tag: \"CodeArtifact\" });\n\t\t});\n\t\tit(\"Set valid props via 'as any' - returned from getTelemetryProperties, overwrites\", () => {\n\t\t\tconst loggingError = new LoggingError(\"myMessage\", { p1: 1, p2: \"two\", p3: true });\n\t\t\tloggingError.addTelemetryProperties({ p1: \"should be overwritten\" });\n\t\t\tconst errorAsAny = loggingError as any;\n\t\t\t// Things that could be set with addTelemetryProperties\n\t\t\terrorAsAny.p1 = \"one\";\n\t\t\terrorAsAny.p4 = 4;\n\t\t\terrorAsAny.p5 = true;\n\t\t\terrorAsAny.p6 = { value: 5, tag: \"CodeArtifact\" };\n\t\t\terrorAsAny.userData6 = { value: 5, tag: \"UserData\" };\n\t\t\terrorAsAny.p7 = [\"a\", \"b\", \"c\"];\n\t\t\terrorAsAny.p8 = [1, 2, 3];\n\t\t\terrorAsAny.p9 = [true, true, false];\n\t\t\terrorAsAny.p10 = { one: \"1\" };\n\t\t\terrorAsAny.p11 = undefined;\n\t\t\terrorAsAny.p12 = { value: [\"1\", 2, true], tag: \"CodeArtifact\" };\n\t\t\t// Things that can't be set with addTelemetryProperties\n\t\t\terrorAsAny.p13 = null; // Null\n\t\t\terrorAsAny.p14 = [\"a\", \"b\", \"c\", null]; // Array with nulls\n\t\t\terrorAsAny.p15 = [[1, 2]]; // Nested array\n\t\t\tconst props = loggingError.getTelemetryProperties();\n\t\t\tassert.strictEqual(props.p1, \"one\");\n\t\t\tassert.strictEqual(props.p4, 4);\n\t\t\tassert.strictEqual(props.p5, true);\n\t\t\tassert.deepStrictEqual(props.p6, { value: 5, tag: \"CodeArtifact\" });\n\t\t\tassert.deepStrictEqual(props.userData6, { value: 5, tag: \"UserData\" });\n\t\t\tassert.strictEqual(props.p7, `[\"a\",\"b\",\"c\"]`);\n\t\t\tassert.strictEqual(props.p8, `[1,2,3]`);\n\t\t\tassert.strictEqual(props.p9, `[true,true,false]`);\n\t\t\tassert.strictEqual(props.p10, `{\"one\":\"1\"}`);\n\t\t\tassert.strictEqual(props.p11, undefined);\n\t\t\tassert.deepStrictEqual(props.p12, { value: `[\"1\",2,true]`, tag: \"CodeArtifact\" });\n\t\t\tassert.strictEqual(props.p13, \"null\");\n\t\t\tassert.strictEqual(props.p14, `[\"a\",\"b\",\"c\",null]`);\n\t\t\tassert.strictEqual(props.p15, \"[[1,2]]\");\n\t\t});\n\t\tit(\"addTelemetryProperties - Does not overwrite base class Error fields (untagged)\", () => {\n\t\t\tconst loggingError = new LoggingError(\"myMessage\");\n\t\t\tconst propsWillBeIgnored = { message: \"surprise1\", stack: \"surprise2\" };\n\t\t\tloggingError.addTelemetryProperties(propsWillBeIgnored);\n\t\t\tconst props = loggingError.getTelemetryProperties();\n\t\t\tdelete props.fluidErrorCode; // It's on there for back compat, not trying to test it here\n\t\t\tconst { message, stack, errorInstanceId } = loggingError;\n\t\t\tassert.deepStrictEqual(\n\t\t\t\tprops,\n\t\t\t\t{ message, stack, errorInstanceId },\n\t\t\t\t\"addTelemetryProperties should not overwrite existing props\",\n\t\t\t);\n\t\t});\n\t\tit(\"addTelemetryProperties - Does not overwrite base class Error fields (tagged)\", () => {\n\t\t\tconst loggingError = new LoggingError(\"myMessage\");\n\t\t\tconst propsWillBeIgnored = {\n\t\t\t\tmessage: { value: \"Mark Fields\", tag: \"UserData\" },\n\t\t\t\tstack: { value: \"surprise2\", tag: \"CodeArtifact\" },\n\t\t\t};\n\t\t\tloggingError.addTelemetryProperties(propsWillBeIgnored);\n\t\t\tconst props = loggingError.getTelemetryProperties();\n\t\t\tdelete props.fluidErrorCode; // It's on there for back compat, not trying to test it here\n\t\t\tconst { message, stack, errorInstanceId } = loggingError;\n\t\t\tassert.deepStrictEqual(\n\t\t\t\tprops,\n\t\t\t\t{ message, stack, errorInstanceId },\n\t\t\t\t\"addTelemetryProperties should not overwrite existing props\",\n\t\t\t);\n\t\t});\n\t\tit(\"addTelemetryProperties - Does not overwrite existing telemetry props\", () => {\n\t\t\tconst loggingError = new LoggingError(\"myMessage\", { p1: 1 });\n\t\t\tloggingError.addTelemetryProperties({ p1: \"one\" });\n\t\t\tassert(loggingError.getTelemetryProperties().p1 === 1);\n\t\t\tloggingError.addTelemetryProperties({ p1: \"uno\" });\n\t\t\tassert(loggingError.getTelemetryProperties().p1 === 1);\n\t\t});\n\t\tit(\"typeCheck - Correctly type checks an instace of LoggingError\", () => {\n\t\t\tconst loggingError = new LoggingError(\"myMessage\", { p1: 1 });\n\t\t\tconst normalizedLoggingError = normalizeError(loggingError);\n\t\t\tconst basicError = new Error(\"basicErrorMessage\");\n\t\t\tassert.strictEqual(\n\t\t\t\tLoggingError.typeCheck(loggingError),\n\t\t\t\ttrue,\n\t\t\t\t\"LoggingError is a LoggingError\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\tLoggingError.typeCheck(normalizedLoggingError),\n\t\t\t\ttrue,\n\t\t\t\t\"Normalized Error is a LoggingError\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\tLoggingError.typeCheck(basicError),\n\t\t\t\tfalse,\n\t\t\t\t\"Error is not a LoggingError\",\n\t\t\t);\n\t\t});\n\t});\n\tdescribe(\"extractLogSafeErrorProperties\", () => {\n\t\tfunction createSampleError(): Error {\n\t\t\ttry {\n\t\t\t\tconst error = new Error(\"asdf\");\n\t\t\t\terror.name = \"FooError\";\n\t\t\t\tthrow error;\n\t\t\t} catch (error) {\n\t\t\t\treturn error as Error;\n\t\t\t}\n\t\t}\n\n\t\tit(\"non-object error yields correct message\", () => {\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties(\"hello\", false /* sanitizeStack */).message,\n\t\t\t\t\"hello\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties(42, false /* sanitizeStack */).message,\n\t\t\t\t\"42\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties(true, false /* sanitizeStack */).message,\n\t\t\t\t\"true\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties(undefined, false /* sanitizeStack */).message,\n\t\t\t\t\"undefined\",\n\t\t\t);\n\t\t});\n\t\tit(\"object error yields correct message\", () => {\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties({ message: \"hello\" }, false /* sanitizeStack */)\n\t\t\t\t\t.message,\n\t\t\t\t\"hello\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties({ message: 42 }, false /* sanitizeStack */).message,\n\t\t\t\t\"[object Object]\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties({ foo: 42 }, false /* sanitizeStack */).message,\n\t\t\t\t\"[object Object]\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties([1, 2, 3], false /* sanitizeStack */).message,\n\t\t\t\t\"1,2,3\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties(null, false /* sanitizeStack */).message,\n\t\t\t\t\"null\",\n\t\t\t);\n\t\t});\n\t\tit(\"extract errorType\", () => {\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties({ errorType: \"hello\" }, false /* sanitizeStack */)\n\t\t\t\t\t.errorType,\n\t\t\t\t\"hello\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties({ foo: \"hello\" }, false /* sanitizeStack */)\n\t\t\t\t\t.errorType,\n\t\t\t\tundefined,\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties({ errorType: 42 }, false /* sanitizeStack */)\n\t\t\t\t\t.errorType,\n\t\t\t\tundefined,\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties(42, false /* sanitizeStack */).errorType,\n\t\t\t\tundefined,\n\t\t\t);\n\t\t});\n\t\tit(\"extract stack\", () => {\n\t\t\tconst e1 = createSampleError();\n\n\t\t\tconst stack = extractLogSafeErrorProperties(e1, false /* sanitizeStack */).stack;\n\t\t\tassert(typeof stack === \"string\");\n\t\t\tassert(stack?.includes(\"asdf\"), \"stack is expected to contain the message\");\n\t\t\tassert(stack?.includes(\"FooError\"), \"stack is expected to contain the name\");\n\n\t\t\tconst sanitizedStack = extractLogSafeErrorProperties(\n\t\t\t\te1,\n\t\t\t\ttrue /* sanitizeStack */,\n\t\t\t).stack;\n\t\t\tassert(typeof sanitizedStack === \"string\");\n\t\t\tassert(\n\t\t\t\t!sanitizedStack?.includes(\"asdf\"),\n\t\t\t\t\"message should have been removed from sanitized stack\",\n\t\t\t);\n\t\t\tassert(\n\t\t\t\tsanitizedStack?.includes(\"FooError\"),\n\t\t\t\t\"name should still be in the sanitized stack\",\n\t\t\t);\n\t\t});\n\t\tit(\"extract stack non-standard values\", () => {\n\t\t\t// sanitizeStack true\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties({ stack: \"hello\" }, true /* sanitizeStack */).stack,\n\t\t\t\t\"\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties(\n\t\t\t\t\t{ stack: \"hello\", name: \"name\" },\n\t\t\t\t\ttrue /* sanitizeStack */,\n\t\t\t\t).stack,\n\t\t\t\t\"name\",\n\t\t\t);\n\t\t\t// sanitizeStack false\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties({ stack: \"hello\" }, false /* sanitizeStack */).stack,\n\t\t\t\t\"hello\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties(\n\t\t\t\t\t{ stack: \"hello\", name: \"name\" },\n\t\t\t\t\tfalse /* sanitizeStack */,\n\t\t\t\t).stack,\n\t\t\t\t\"hello\",\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties({ foo: \"hello\" }, false /* sanitizeStack */).stack,\n\t\t\t\tundefined,\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties({ stack: 42 }, false /* sanitizeStack */).stack,\n\t\t\t\tundefined,\n\t\t\t);\n\t\t\tassert.strictEqual(\n\t\t\t\textractLogSafeErrorProperties(42, false /* sanitizeStack */).stack,\n\t\t\t\tundefined,\n\t\t\t);\n\t\t});\n\t});\n\tdescribe(\"normalizeError\", () => {\n\t\tdescribe(\"preserves properties\", () => {\n\t\t\tit(\"missing properties are not set\", () => {\n\t\t\t\t// eslint-disable-next-line unicorn/error-message\n\t\t\t\tconst unknownError = new Error();\n\n\t\t\t\tconst newError: IFluidErrorBase & {\n\t\t\t\t\tcanRetry?: boolean;\n\t\t\t\t\tretryAfterSeconds?: number;\n\t\t\t\t} = normalizeError(unknownError);\n\n\t\t\t\tassert.strictEqual(newError.canRetry, undefined, \"canRetry not undefined\");\n\t\t\t\tassert.strictEqual(\n\t\t\t\t\tnewError.retryAfterSeconds,\n\t\t\t\t\tundefined,\n\t\t\t\t\t\"retryAfterSeconds not undefined\",\n\t\t\t\t);\n\t\t\t});\n\t\t\tit(\"existing retry properties are present in normalized error\", () => {\n\t\t\t\tconst unknownError: { canRetry?: boolean; retryAfterSeconds?: number } & Error =\n\t\t\t\t\t// eslint-disable-next-line unicorn/error-message\n\t\t\t\t\tnew Error();\n\t\t\t\tunknownError.canRetry = true;\n\t\t\t\tunknownError.retryAfterSeconds = 100;\n\n\t\t\t\tconst newError: IFluidErrorBase & {\n\t\t\t\t\tcanRetry?: boolean;\n\t\t\t\t\tretryAfterSeconds?: number;\n\t\t\t\t} = normalizeError(unknownError);\n\n\t\t\t\tassert.strictEqual(newError.canRetry, true, \"canRetry not true\");\n\t\t\t\tassert.strictEqual(newError.retryAfterSeconds, 100, \"retryAfterSeconds not 100\");\n\t\t\t});\n\t\t});\n\t});\n});\n\nclass TestFluidError implements IFluidErrorBase {\n\treadonly atpStub: sinon.SinonStub;\n\treadonly gtpSpy: sinon.SinonSpy;\n\texpectedTelemetryProps: ITelemetryBaseProperties;\n\n\treadonly errorType: string;\n\treadonly message: string;\n\treadonly stack?: string;\n\treadonly name: string = \"Error\";\n\treadonly errorInstanceId: string;\n\n\tconstructor(\n\t\terrorProps: Omit<\n\t\t\tIFluidErrorBase,\n\t\t\t\"getTelemetryProperties\" | \"addTelemetryProperties\" | \"errorInstanceId\" | \"name\"\n\t\t>,\n\t) {\n\t\tthis.errorType = errorProps.errorType;\n\t\tthis.message = errorProps.message;\n\t\tthis.stack = errorProps.stack;\n\t\tthis.errorInstanceId = uuid();\n\n\t\tthis.atpStub = sinon.stub(this, \"addTelemetryProperties\");\n\t\tthis.gtpSpy = sinon.spy(this, \"getTelemetryProperties\");\n\t\tthis.expectedTelemetryProps = { ...errorProps };\n\t}\n\n\tgetTelemetryProperties(): ITelemetryBaseProperties {\n\t\t// Don't actually return any props. We'll use the spy to ensure it was called\n\t\treturn {};\n\t}\n\n\taddTelemetryProperties(props: ITelemetryPropertiesExt): void {\n\t\tthrow new Error(\"Not Implemented - Expected to be Stubbed via Sinon\");\n\t}\n\n\twithoutProperty(propName: keyof IFluidErrorBase): this {\n\t\tconst objectWithoutProp = {};\n\t\tobjectWithoutProp[propName] = undefined;\n\t\tObject.assign(this, objectWithoutProp);\n\t\treturn this;\n\t}\n\n\twithExpectedTelemetryProps(props: ITelemetryBaseProperties): this {\n\t\tObject.assign(this.expectedTelemetryProps, props);\n\t\treturn this;\n\t}\n}\n\nconst annotationCases: Record<string, IFluidErrorAnnotations> = {\n\tnoAnnotations: {},\n\tjustProps: { props: { foo: \"bar\", one: 1, u: undefined, t: true } },\n};\n\ndescribe(\"normalizeError\", () => {\n\tdescribe(\"Valid Errors (Legacy and Current)\", () => {\n\t\tfor (const annotationCase of Object.keys(annotationCases)) {\n\t\t\tconst annotations = annotationCases[annotationCase];\n\t\t\tit(`Valid legacy error - Patch and return (annotations: ${annotationCase})`, () => {\n\t\t\t\t// Arrange\n\t\t\t\tconst errorProps = { errorType: \"et1\", message: \"m1\" };\n\t\t\t\tconst legacyError = new TestFluidError(errorProps).withoutProperty(\n\t\t\t\t\t\"errorInstanceId\",\n\t\t\t\t);\n\n\t\t\t\t// Act\n\t\t\t\tconst normalizedError = normalizeError(legacyError, annotations);\n\n\t\t\t\t// Assert\n\t\t\t\tassert.equal(\n\t\t\t\t\tnormalizedError,\n\t\t\t\t\tlegacyError,\n\t\t\t\t\t\"normalize should yield the same error as passed in\",\n\t\t\t\t);\n\t\t\t\tassert.equal(normalizedError.errorType, \"et1\", \"errorType should be unchanged\");\n\t\t\t\tassert.equal(normalizedError.message, \"m1\", \"message should be unchanged\");\n\t\t\t\tassert.equal(normalizedError.errorInstanceId.length, 36, \"should be guid-length\");\n\t\t\t\tif (annotations.props !== undefined) {\n\t\t\t\t\tassert(\n\t\t\t\t\t\tlegacyError.atpStub.calledWith(annotations.props),\n\t\t\t\t\t\t\"addTelemetryProperties should have been called\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t});\n\t\t\tit(`Valid Fluid Error - untouched (annotations: ${annotationCase})`, () => {\n\t\t\t\t// Arrange\n\t\t\t\tconst fluidError = new TestFluidError({ errorType: \"et1\", message: \"m1\" });\n\t\t\t\t// We don't expect legacyError to be modified itself at all\n\t\t\t\tObject.freeze(fluidError);\n\n\t\t\t\t// Act\n\t\t\t\tconst normalizedError = normalizeError(fluidError, annotations);\n\n\t\t\t\t// Assert\n\t\t\t\tassert(normalizedError === fluidError);\n\t\t\t\tif (annotations.props !== undefined) {\n\t\t\t\t\tassert(\n\t\t\t\t\t\tfluidError.atpStub.calledWith(annotations.props),\n\t\t\t\t\t\t\"addTelemetryProperties should have been called\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tit(\"Valid Fluid Error - stack not added if missing\", () => {\n\t\t\t// Arrange\n\t\t\tconst fluidError = new TestFluidError({\n\t\t\t\terrorType: \"et1\",\n\t\t\t\tmessage: \"m1\",\n\t\t\t}).withoutProperty(\"stack\");\n\t\t\t// We don't expect legacyError to be modified itself at all\n\t\t\tObject.freeze(fluidError);\n\n\t\t\t// Act\n\t\t\tconst normalizedError = normalizeError(fluidError, {});\n\n\t\t\t// Assert\n\t\t\tassert(normalizedError === fluidError);\n\t\t\tassert(normalizedError.stack === undefined);\n\t\t});\n\t\tit(\"Frozen legacy error - Throws\", () => {\n\t\t\t// Arrange\n\t\t\tconst errorProps = { errorType: \"et1\", message: \"m1\" };\n\t\t\tconst legacyError = new TestFluidError(errorProps).withoutProperty(\"errorInstanceId\");\n\t\t\tObject.freeze(legacyError);\n\n\t\t\t// Act/Assert\n\t\t\tassert.throws(\n\t\t\t\t() => normalizeError(legacyError, {}),\n\t\t\t\t/Cannot assign to read only property/,\n\t\t\t);\n\t\t});\n\t});\n\tdescribe(\"Errors Needing Normalization\", () => {\n\t\tclass NamedError extends Error {\n\t\t\tname = \"CoolErrorName\";\n\t\t}\n\t\tconst sampleFluidError = (): TestFluidError =>\n\t\t\tnew TestFluidError({\n\t\t\t\terrorType: \"someType\",\n\t\t\t\tmessage: \"Hello\",\n\t\t\t\tstack: \"cool stack trace\",\n\t\t\t});\n\t\tconst typicalOutput = (\n\t\t\tmessage: string,\n\t\t\tstackHint: \"<<natural stack>>\" | \"<<stack from input>>\",\n\t\t): TestFluidError =>\n\t\t\tnew TestFluidError({\n\t\t\t\terrorType: \"genericError\",\n\t\t\t\tmessage,\n\t\t\t\tstack: stackHint,\n\t\t\t});\n\t\tconst testCases: { [label: string]: () => { input: any; expectedOutput: TestFluidError } } =\n\t\t\t{\n\t\t\t\t\"Fluid Error minus errorType\": () => ({\n\t\t\t\t\tinput: sampleFluidError().withoutProperty(\"errorType\"),\n\t\t\t\t\texpectedOutput: typicalOutput(\"Hello\", \"<<stack from input>>\"),\n\t\t\t\t}),\n\t\t\t\t\"Fluid Error minus message\": () => ({\n\t\t\t\t\tinput: sampleFluidError().withoutProperty(\"message\"),\n\t\t\t\t\texpectedOutput: typicalOutput(\"[object Object]\", \"<<stack from input>>\"),\n\t\t\t\t}),\n\t\t\t\t\"Fluid Error minus getTelemetryProperties\": () => ({\n\t\t\t\t\tinput: sampleFluidError().withoutProperty(\"getTelemetryProperties\"),\n\t\t\t\t\texpectedOutput: typicalOutput(\"Hello\", \"<<stack from input>>\"),\n\t\t\t\t}),\n\t\t\t\t\"Fluid Error minus addTelemetryProperties\": () => ({\n\t\t\t\t\tinput: sampleFluidError().withoutProperty(\"addTelemetryProperties\"),\n\t\t\t\t\texpectedOutput: typicalOutput(\"Hello\", \"<<stack from input>>\"),\n\t\t\t\t}),\n\t\t\t\t\"Fluid Error minus errorType (no stack)\": () => ({\n\t\t\t\t\tinput: sampleFluidError().withoutProperty(\"errorType\").withoutProperty(\"stack\"),\n\t\t\t\t\texpectedOutput: typicalOutput(\"Hello\", \"<<natural stack>>\"),\n\t\t\t\t}),\n\t\t\t\t\"Fluid Error minus message (no stack)\": () => ({\n\t\t\t\t\tinput: sampleFluidError().withoutProperty(\"message\").withoutProperty(\"stack\"),\n\t\t\t\t\texpectedOutput: typicalOutput(\"[object Object]\", \"<<natural stack>>\"),\n\t\t\t\t}),\n\t\t\t\t\"Error object\": () => ({\n\t\t\t\t\tinput: new NamedError(\"boom\"),\n\t\t\t\t\texpectedOutput: typicalOutput(\n\t\t\t\t\t\t\"boom\",\n\t\t\t\t\t\t\"<<stack from input>>\",\n\t\t\t\t\t).withExpectedTelemetryProps({ untrustedOrigin: 1 }),\n\t\t\t\t}),\n\t\t\t\t\"LoggingError\": () => ({\n\t\t\t\t\tinput: new LoggingError(\"boom\"),\n\t\t\t\t\texpectedOutput: typicalOutput(\"boom\", \"<<stack from input>>\"),\n\t\t\t\t}),\n\t\t\t\t\"Empty object\": () => ({\n\t\t\t\t\tinput: {},\n\t\t\t\t\texpectedOutput: typicalOutput(\n\t\t\t\t\t\t\"[object Object]\",\n\t\t\t\t\t\t\"<<natural stack>>\",\n\t\t\t\t\t).withExpectedTelemetryProps({ untrustedOrigin: 1 }),\n\t\t\t\t}),\n\t\t\t\t\"object with stack\": () => ({\n\t\t\t\t\tinput: { message: \"whatever\", stack: \"fake stack goes here\" },\n\t\t\t\t\texpectedOutput: typicalOutput(\n\t\t\t\t\t\t\"whatever\",\n\t\t\t\t\t\t\"<<stack from input>>\",\n\t\t\t\t\t).withExpectedTelemetryProps({ untrustedOrigin: 1 }),\n\t\t\t\t}),\n\t\t\t\t\"object with non-string message and name\": () => ({\n\t\t\t\t\tinput: { message: 42, name: true },\n\t\t\t\t\texpectedOutput: typicalOutput(\n\t\t\t\t\t\t\"[object Object]\",\n\t\t\t\t\t\t\"<<natural stack>>\",\n\t\t\t\t\t).withExpectedTelemetryProps({ untrustedOrigin: 1 }),\n\t\t\t\t}),\n\t\t\t\t\"nullValue\": () => ({\n\t\t\t\t\tinput: null,\n\t\t\t\t\texpectedOutput: typicalOutput(\n\t\t\t\t\t\t\"null\",\n\t\t\t\t\t\t\"<<natural stack>>\",\n\t\t\t\t\t).withExpectedTelemetryProps({ untrustedOrigin: 1 }),\n\t\t\t\t}),\n\t\t\t\t\"undef\": () => ({\n\t\t\t\t\tinput: undefined,\n\t\t\t\t\texpectedOutput: typicalOutput(\n\t\t\t\t\t\t\"undefined\",\n\t\t\t\t\t\t\"<<natural stack>>\",\n\t\t\t\t\t).withExpectedTelemetryProps({ typeofError: \"undefined\", untrustedOrigin: 1 }),\n\t\t\t\t}),\n\t\t\t\t\"false\": () => ({\n\t\t\t\t\tinput: false,\n\t\t\t\t\texpectedOutput: typicalOutput(\n\t\t\t\t\t\t\"false\",\n\t\t\t\t\t\t\"<<natural stack>>\",\n\t\t\t\t\t).withExpectedTelemetryProps({ typeofError: \"boolean\", untrustedOrigin: 1 }),\n\t\t\t\t}),\n\t\t\t\t\"true\": () => ({\n\t\t\t\t\tinput: true,\n\t\t\t\t\texpectedOutput: typicalOutput(\n\t\t\t\t\t\t\"true\",\n\t\t\t\t\t\t\"<<natural stack>>\",\n\t\t\t\t\t).withExpectedTelemetryProps({ typeofError: \"boolean\", untrustedOrigin: 1 }),\n\t\t\t\t}),\n\t\t\t\t\"number\": () => ({\n\t\t\t\t\tinput: 3.14,\n\t\t\t\t\texpectedOutput: typicalOutput(\n\t\t\t\t\t\t\"3.14\",\n\t\t\t\t\t\t\"<<natural stack>>\",\n\t\t\t\t\t).withExpectedTelemetryProps({ typeofError: \"number\", untrustedOrigin: 1 }),\n\t\t\t\t}),\n\t\t\t\t\"symbol\": () => ({\n\t\t\t\t\tinput: Symbol(\"Unique\"),\n\t\t\t\t\texpectedOutput: typicalOutput(\n\t\t\t\t\t\t\"Symbol(Unique)\",\n\t\t\t\t\t\t\"<<natural stack>>\",\n\t\t\t\t\t).withExpectedTelemetryProps({ typeofError: \"symbol\", untrustedOrigin: 1 }),\n\t\t\t\t}),\n\t\t\t\t\"function\": () => ({\n\t\t\t\t\tinput: (): void => {},\n\t\t\t\t\texpectedOutput: typicalOutput(\n\t\t\t\t\t\t\"() => { }\",\n\t\t\t\t\t\t\"<<natural stack>>\",\n\t\t\t\t\t).withExpectedTelemetryProps({ typeofError: \"function\", untrustedOrigin: 1 }),\n\t\t\t\t}),\n\t\t\t\t\"emptyArray\": () => ({\n\t\t\t\t\tinput: [],\n\t\t\t\t\texpectedOutput: typicalOutput(\n\t\t\t\t\t\t\"\",\n\t\t\t\t\t\t\"<<natural stack>>\",\n\t\t\t\t\t).withExpectedTelemetryProps({ untrustedOrigin: 1 }),\n\t\t\t\t}),\n\t\t\t\t\"array\": () => ({\n\t\t\t\t\tinput: [1, 2, 3],\n\t\t\t\t\texpectedOutput: typicalOutput(\n\t\t\t\t\t\t\"1,2,3\",\n\t\t\t\t\t\t\"<<natural stack>>\",\n\t\t\t\t\t).withExpectedTelemetryProps({ untrustedOrigin: 1 }),\n\t\t\t\t}),\n\t\t\t};\n\t\tfunction assertMatching(\n\t\t\tactual: IFluidErrorBase,\n\t\t\texpected: TestFluidError,\n\t\t\tannotations: IFluidErrorAnnotations = {},\n\t\t\tinputStack: string | undefined,\n\t\t): void {\n\t\t\texpected.withExpectedTelemetryProps({\n\t\t\t\t...annotations.props,\n\t\t\t\terrorInstanceId: actual.errorInstanceId,\n\t\t\t\tfluidErrorCode: \"-\", // Present for back-compat\n\t\t\t});\n\n\t\t\tassertMatchingMessageAndStack(actual, expected, inputStack);\n\n\t\t\tassert.equal(actual.errorType, expected.errorType, \"errorType should match\");\n\t\t\tassert.equal(actual.name, expected.name, \"name should match\");\n\t\t\tassert.equal(actual.errorInstanceId.length, 36, \"should be guid-length\");\n\t\t\tassert.deepStrictEqual(\n\t\t\t\tactual.getTelemetryProperties(),\n\t\t\t\texpected.expectedTelemetryProps,\n\t\t\t\t\"telemetry props should match\",\n\t\t\t);\n\t\t}\n\t\tfunction assertMatchingMessageAndStack(\n\t\t\tactual: IFluidErrorBase,\n\t\t\texpected: TestFluidError,\n\t\t\tinputStack: string | undefined,\n\t\t): void {\n\t\t\tassert.equal(actual.message, expected.message, \"message should match\");\n\t\t\tconst actualStack = actual.stack;\n\t\t\tassert(actualStack !== undefined, \"stack should be present as a string\");\n\t\t\tif (actualStack.includes(\"at normalizeError\")) {\n\t\t\t\t// This indicates the stack was populated naturally by new SimpleFluidError\n\t\t\t\tassert.equal(\n\t\t\t\t\texpected.stack,\n\t\t\t\t\t\"<<natural stack>>\",\n\t\t\t\t\t\"<<natural stack>> hint should be used if not overwritten\",\n\t\t\t\t);\n\t\t\t\texpected.withExpectedTelemetryProps({ stack: actualStack });\n\t\t\t} else {\n\t\t\t\tassert.equal(\n\t\t\t\t\tactualStack,\n\t\t\t\t\tinputStack,\n\t\t\t\t\t\"If stack wasn't generated, it should match input stack\",\n\t\t\t\t);\n\t\t\t\tassert.equal(\n\t\t\t\t\texpected.stack,\n\t\t\t\t\t\"<<stack from input>>\",\n\t\t\t\t\t\"<<stack from input>> hint should be used if using stack from input error object\",\n\t\t\t\t);\n\t\t\t\texpected.withExpectedTelemetryProps({ stack: inputStack });\n\t\t\t}\n\t\t}\n\t\tfor (const annotationCase of Object.keys(annotationCases)) {\n\t\t\tconst annotations = annotationCases[annotationCase];\n\t\t\tlet doneOnceForThisAnnotationCase = false;\n\t\t\tfor (const caseName of Object.keys(testCases)) {\n\t\t\t\tconst getTestCase = testCases[caseName];\n\t\t\t\tif (!doneOnceForThisAnnotationCase) {\n\t\t\t\t\tdoneOnceForThisAnnotationCase = true;\n\t\t\t\t\t// Each test case only differs by what stack/error are. Test the rest only once per annotation case.\n\t\t\t\t\tit(`Normalize untrusted error full validation: (${annotationCase})`, () => {\n\t\t\t\t\t\t// Arrange\n\t\t\t\t\t\tconst { input, expectedOutput } = getTestCase();\n\n\t\t\t\t\t\t// Act\n\t\t\t\t\t\tconst normalized = normalizeError(input, annotations);\n\n\t\t\t\t\t\t// Assert\n\t\t\t\t\t\tassert.notEqual(\n\t\t\t\t\t\t\tinput,\n\t\t\t\t\t\t\tnormalized,\n\t\t\t\t\t\t\t\"input should have yielded a new error object\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\tassertMatching(normalized, expectedOutput, annotations, input?.stack);\n\t\t\t\t\t\tif (\n\t\t\t\t\t\t\tinput instanceof TestFluidError &&\n\t\t\t\t\t\t\tinput.getTelemetryProperties !== undefined\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\tassert(\n\t\t\t\t\t\t\t\tinput.gtpSpy.calledOnce,\n\t\t\t\t\t\t\t\t\"input.getTelemetryProperties should have been called by normalizeError\",\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Bonus\n\t\t\t\t\t\tnormalized.addTelemetryProperties({ foo: \"bar\" });\n\t\t\t\t\t\tassert.equal(\n\t\t\t\t\t\t\tnormalized.getTelemetryProperties().foo,\n\t\t\t\t\t\t\t\"bar\",\n\t\t\t\t\t\t\t\"can add telemetry props after normalization\",\n\t\t\t\t\t\t);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tit(`Normalize untrusted error message/stack: ${caseName} (${annotationCase})`, () => {\n\t\t\t\t\t// Arrange\n\t\t\t\t\tconst { input, expectedOutput } = getTestCase();\n\n\t\t\t\t\t// Act\n\t\t\t\t\tconst normalized = normalizeError(input, annotations);\n\n\t\t\t\t\t// Assert\n\t\t\t\t\tassert.notEqual(\n\t\t\t\t\t\tinput,\n\t\t\t\t\t\tnormalized,\n\t\t\t\t\t\t\"input should have yielded a new error object\",\n\t\t\t\t\t);\n\t\t\t\t\tassertMatchingMessageAndStack(normalized, expectedOutput, input?.stack);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t});\n});\n\n/**\n * Create an error missing errorType that will not be recognized as a valid Fluid error\n */\nconst createExternalError = (m: string): Error => new Error(m);\n\n/**\n * Create a simple valid Fluid error\n */\nconst createTestError = (\n\tm: string,\n): LoggingError & {\n\terrorType: string;\n} =>\n\tObject.assign(new LoggingError(m), {\n\t\terrorType: \"someErrorType\",\n\t});\n\ndescribe(\"wrapError\", () => {\n\tit(\"Copy message, stack, and props\", () => {\n\t\tconst innerError = new LoggingError(\"hello\", { someProp: 123 });\n\t\tinnerError.stack = \"extra special stack\";\n\t\tconst newError = wrapError(innerError, createTestError);\n\t\tassert.equal(newError.message, innerError.message, \"messages should match\");\n\t\tassert.equal(newError.stack, innerError.stack, \"stacks should match\");\n\t\tassert.equal(newError.getTelemetryProperties().someProp, 123, \"Props should be preserved\");\n\t});\n\tit(\"Include matching errorInstanceId and innerErrorInstanceId in telemetry props\", () => {\n\t\tconst innerError = new LoggingError(\"hello\");\n\t\tconst newError = wrapError(innerError, createTestError);\n\t\tassert(newError.errorInstanceId === innerError.errorInstanceId);\n\t\tassert(\n\t\t\tnewError.getTelemetryProperties().innerErrorInstanceId === innerError.errorInstanceId,\n\t\t);\n\t});\n\tit(\"Properly set untrustedOrigin\", () => {\n\t\tconst untrustedError = createExternalError(\"untrusted\");\n\n\t\tconst singleWrapped = wrapError(untrustedError, createTestError);\n\t\tassert(\n\t\t\tsingleWrapped.getTelemetryProperties().untrustedOrigin === 1,\n\t\t\t\"wrapped external error should be 'untrustedOrigin'\",\n\t\t);\n\n\t\tconst doubleWrapped = wrapError(singleWrapped, createTestError);\n\t\tassert(\n\t\t\tdoubleWrapped.getTelemetryProperties().untrustedOrigin === 1,\n\t\t\t\"doubly-wrapped external error should be 'untrustedOrigin'\",\n\t\t);\n\n\t\tconst normalizedError = normalizeError(untrustedError);\n\t\tconst wrappedNormalized = wrapError(normalizedError, createTestError);\n\t\tassert(\n\t\t\twrappedNormalized.getTelemetryProperties().untrustedOrigin === 1,\n\t\t\t\"normalized-then-wrapped external error should be 'untrustedOrigin'\",\n\t\t);\n\n\t\tconst trustedError = createTestError(\"trusted\");\n\t\tconst wrappedTrusted = wrapError(trustedError, createTestError);\n\t\tassert(\n\t\t\twrappedTrusted.getTelemetryProperties().untrustedOrigin === undefined,\n\t\t\t\"wrapped Fluid error should not be 'untrustedOrigin'\",\n\t\t);\n\t});\n});\ndescribe(\"wrapErrorAndLog\", () => {\n\tconst mockLogger = new MockLogger();\n\tconst innerError = new LoggingError(\"hello\");\n\tconst newError = wrapErrorAndLog(innerError, createTestError, mockLogger.toTelemetryLogger());\n\tassert(\n\t\tmockLogger.matchEvents([\n\t\t\t{\n\t\t\t\teventName: \"WrapError\",\n\t\t\t\twrappedByErrorInstanceId: newError.errorInstanceId,\n\t\t\t\terrorInstanceId: newError.errorInstanceId,\n\t\t\t\terror: \"hello\",\n\t\t\t},\n\t\t]),\n\t\t\"Expected the 'WrapError' event to be logged\",\n\t);\n});\n\ndescribe(\"Error Discovery\", () => {\n\tit(\"isExternalError\", () => {\n\t\tassert(isExternalError(\"some string\"));\n\t\tassert(isExternalError(createExternalError(\"error message\")));\n\t\tassert(isExternalError(normalizeError(\"normalize me but I'm still external\")));\n\t\tassert(\n\t\t\tisExternalError(\n\t\t\t\tnormalizeError(createExternalError(\"normalize me but I'm still external\")),\n\t\t\t),\n\t\t);\n\n\t\tassert(!isExternalError(createTestError(\"hello\")));\n\n\t\tconst wrappedError = wrapError(\"wrap me\", createTestError);\n\t\tassert(!isExternalError(wrappedError));\n\t\tassert(wrappedError.getTelemetryProperties().untrustedOrigin === 1); // But it should still say untrustedOrigin\n\t\tassert(!isExternalError(new LoggingError(\"testLoggingError\")));\n\t});\n\tit(\"isValidLegacyError\", () => {\n\t\tconst validLegacyError = {\n\t\t\tmessage: \"testMessage\",\n\t\t\terrorType: \"someErrorType\",\n\t\t\tgetTelemetryProperties: (): void => {},\n\t\t\taddTelemetryProperties: (): void => {},\n\t\t};\n\t\tassert.strictEqual(isValidLegacyError(validLegacyError), true);\n\t\tassert.strictEqual(isValidLegacyError({ ...validLegacyError, message: undefined }), false);\n\t\tassert.strictEqual(\n\t\t\tisValidLegacyError({ ...validLegacyError, errorType: undefined }),\n\t\t\tfalse,\n\t\t);\n\t\tassert.strictEqual(\n\t\t\tisValidLegacyError({ ...validLegacyError, getTelemetryProperties: undefined }),\n\t\t\tfalse,\n\t\t);\n\t\tassert.strictEqual(\n\t\t\tisValidLegacyError({ ...validLegacyError, addTelemetryProperties: undefined }),\n\t\t\tfalse,\n\t\t);\n\t});\n\n\t// I copied the old version of isFluidError here, it depends on fluidErrorCode.\n\t// I want to make sure that an error built on LoggingError that otherwise matches isFluidError\n\t// will match isFluidError in old code (e.g. when an error flows across layers)\n\tfunction isFluidError_old(e: any): e is IFluidErrorBase {\n\t\tconst hasTelemetryPropFunctions = (x: any): boolean =>\n\t\t\ttypeof x?.getTelemetryProperties === \"function\" &&\n\t\t\ttypeof x?.addTelemetryProperties === \"function\";\n\t\treturn (\n\t\t\ttypeof e?.errorType === \"string\" &&\n\t\t\ttypeof e?.fluidErrorCode === \"string\" &&\n\t\t\ttypeof e?.message === \"string\" &&\n\t\t\thasErrorInstanceId(e) &&\n\t\t\thasTelemetryPropFunctions(e)\n\t\t);\n\t}\n\n\tfunction testFluidError(isFluidErrorImpl: (e: any) => boolean, isOld: boolean): void {\n\t\tit(`isFluidError${isOld ? \"_old\" : \"\"}`, () => {\n\t\t\tassert(\n\t\t\t\t!isFluidErrorImpl(new Error(\"hello\")),\n\t\t\t\t\"Plain Error object is not a Fluid Error\",\n\t\t\t);\n\t\t\tassert(\n\t\t\t\t!isFluidErrorImpl(new LoggingError(\"hello\")),\n\t\t\t\t\"LoggingError is not a Fluid Error (no errorType)\",\n\t\t\t);\n\t\t\tassert(\n\t\t\t\t!isFluidErrorImpl(\n\t\t\t\t\tObject.assign(new Error(\"hello\"), {\n\t\t\t\t\t\terrorType: \"someErrorType\",\n\t\t\t\t\t\t_errorInstanceId: \"12345\",\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t\t\"Error with errorType and errorInstanceId but without telemetry prop fns is not a Fluid Error\",\n\t\t\t);\n\t\t\tassert(\n\t\t\t\t!isFluidErrorImpl(createExternalError(\"hello\")),\n\t\t\t\t\"Error without errorType is not a Fluid Error\",\n\t\t\t);\n\t\t\tassert(\n\t\t\t\t!isFluidErrorImpl(\n\t\t\t\t\tObject.assign(createTestError(\"hello\"), { _errorInstanceId: undefined }),\n\t\t\t\t),\n\t\t\t\t\"Valid Fluid Error with errorInstanceId removed is not a Fluid Error\",\n\t\t\t);\n\t\t\tassert(\n\t\t\t\tisFluidErrorImpl(createTestError(\"hello\")),\n\t\t\t\t\"Valid Fluid Error is a Fluid Error\",\n\t\t\t);\n\t\t\tassert.equal(\n\t\t\t\t!isOld,\n\t\t\t\tisFluidErrorImpl(\n\t\t\t\t\tObject.assign(createTestError(\"hello\"), { fluidErrorCode: undefined }),\n\t\t\t\t),\n\t\t\t\t\"Old isFluidError impl should require fluidErrorCode but New should not\",\n\t\t\t);\n\t\t});\n\t}\n\ttestFluidError(isFluidError, false /* isOld */);\n\ttestFluidError(isFluidError_old, true /* isOld */);\n});\n"]}
|
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { strict as assert } from "node:assert";
|
|
6
6
|
import { FluidErrorTypes } from "@fluidframework/core-interfaces";
|
|
7
|
-
import {
|
|
8
|
-
import { MockLogger } from "../mockLogger.js";
|
|
7
|
+
import { DataCorruptionError, GenericError } from "../error.js";
|
|
9
8
|
import { createChildLogger } from "../logger.js";
|
|
9
|
+
import { MockLogger } from "../mockLogger.js";
|
|
10
10
|
describe("Check if the errorType field matches after sending/receiving via Container error classes", () => {
|
|
11
11
|
// In all tests below, the `stack` prop will be left out of validation because it is difficult to properly
|
|
12
12
|
// mock a stack for a mocked error.
|