@fluidframework/telemetry-utils 2.0.0-dev.5.2.0.169897 → 2.0.0-dev.6.4.0.191258

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/.eslintrc.js +2 -1
  2. package/CHANGELOG.md +126 -0
  3. package/README.md +4 -3
  4. package/dist/config.d.ts +4 -2
  5. package/dist/config.d.ts.map +1 -1
  6. package/dist/config.js +36 -38
  7. package/dist/config.js.map +1 -1
  8. package/dist/error.d.ts +92 -0
  9. package/dist/error.d.ts.map +1 -0
  10. package/dist/error.js +133 -0
  11. package/dist/error.js.map +1 -0
  12. package/dist/errorLogging.d.ts +44 -19
  13. package/dist/errorLogging.d.ts.map +1 -1
  14. package/dist/errorLogging.js +70 -31
  15. package/dist/errorLogging.js.map +1 -1
  16. package/dist/eventEmitterWithErrorHandling.d.ts +3 -3
  17. package/dist/eventEmitterWithErrorHandling.d.ts.map +1 -1
  18. package/dist/eventEmitterWithErrorHandling.js +10 -3
  19. package/dist/eventEmitterWithErrorHandling.js.map +1 -1
  20. package/dist/events.d.ts +1 -1
  21. package/dist/events.d.ts.map +1 -1
  22. package/dist/events.js.map +1 -1
  23. package/dist/fluidErrorBase.d.ts +49 -16
  24. package/dist/fluidErrorBase.d.ts.map +1 -1
  25. package/dist/fluidErrorBase.js +21 -14
  26. package/dist/fluidErrorBase.js.map +1 -1
  27. package/dist/index.d.ts +5 -5
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +16 -8
  30. package/dist/index.js.map +1 -1
  31. package/dist/logger.d.ts +98 -60
  32. package/dist/logger.d.ts.map +1 -1
  33. package/dist/logger.js +193 -124
  34. package/dist/logger.js.map +1 -1
  35. package/dist/mockLogger.d.ts +17 -8
  36. package/dist/mockLogger.d.ts.map +1 -1
  37. package/dist/mockLogger.js +49 -28
  38. package/dist/mockLogger.js.map +1 -1
  39. package/dist/sampledTelemetryHelper.d.ts +9 -8
  40. package/dist/sampledTelemetryHelper.d.ts.map +1 -1
  41. package/dist/sampledTelemetryHelper.js +21 -16
  42. package/dist/sampledTelemetryHelper.js.map +1 -1
  43. package/dist/telemetryTypes.d.ts +20 -6
  44. package/dist/telemetryTypes.d.ts.map +1 -1
  45. package/dist/telemetryTypes.js.map +1 -1
  46. package/dist/thresholdCounter.d.ts.map +1 -1
  47. package/dist/thresholdCounter.js.map +1 -1
  48. package/dist/utils.d.ts +3 -3
  49. package/dist/utils.d.ts.map +1 -1
  50. package/dist/utils.js +2 -2
  51. package/dist/utils.js.map +1 -1
  52. package/lib/config.d.ts +4 -2
  53. package/lib/config.d.ts.map +1 -1
  54. package/lib/config.js +34 -37
  55. package/lib/config.js.map +1 -1
  56. package/lib/error.d.ts +92 -0
  57. package/lib/error.d.ts.map +1 -0
  58. package/lib/error.js +125 -0
  59. package/lib/error.js.map +1 -0
  60. package/lib/errorLogging.d.ts +44 -19
  61. package/lib/errorLogging.d.ts.map +1 -1
  62. package/lib/errorLogging.js +69 -31
  63. package/lib/errorLogging.js.map +1 -1
  64. package/lib/eventEmitterWithErrorHandling.d.ts +3 -3
  65. package/lib/eventEmitterWithErrorHandling.d.ts.map +1 -1
  66. package/lib/eventEmitterWithErrorHandling.js +9 -2
  67. package/lib/eventEmitterWithErrorHandling.js.map +1 -1
  68. package/lib/events.d.ts +1 -1
  69. package/lib/events.d.ts.map +1 -1
  70. package/lib/events.js.map +1 -1
  71. package/lib/fluidErrorBase.d.ts +49 -16
  72. package/lib/fluidErrorBase.d.ts.map +1 -1
  73. package/lib/fluidErrorBase.js +21 -14
  74. package/lib/fluidErrorBase.js.map +1 -1
  75. package/lib/index.d.ts +5 -5
  76. package/lib/index.d.ts.map +1 -1
  77. package/lib/index.js +4 -4
  78. package/lib/index.js.map +1 -1
  79. package/lib/logger.d.ts +98 -60
  80. package/lib/logger.d.ts.map +1 -1
  81. package/lib/logger.js +184 -119
  82. package/lib/logger.js.map +1 -1
  83. package/lib/mockLogger.d.ts +17 -8
  84. package/lib/mockLogger.d.ts.map +1 -1
  85. package/lib/mockLogger.js +50 -29
  86. package/lib/mockLogger.js.map +1 -1
  87. package/lib/sampledTelemetryHelper.d.ts +9 -8
  88. package/lib/sampledTelemetryHelper.d.ts.map +1 -1
  89. package/lib/sampledTelemetryHelper.js +19 -14
  90. package/lib/sampledTelemetryHelper.js.map +1 -1
  91. package/lib/telemetryTypes.d.ts +20 -6
  92. package/lib/telemetryTypes.d.ts.map +1 -1
  93. package/lib/telemetryTypes.js.map +1 -1
  94. package/lib/thresholdCounter.d.ts.map +1 -1
  95. package/lib/thresholdCounter.js.map +1 -1
  96. package/lib/utils.d.ts +3 -3
  97. package/lib/utils.d.ts.map +1 -1
  98. package/lib/utils.js +2 -2
  99. package/lib/utils.js.map +1 -1
  100. package/package.json +21 -44
  101. package/src/config.ts +25 -15
  102. package/src/error.ts +202 -0
  103. package/src/errorLogging.ts +102 -57
  104. package/src/eventEmitterWithErrorHandling.ts +5 -3
  105. package/src/events.ts +3 -3
  106. package/src/fluidErrorBase.ts +63 -27
  107. package/src/index.ts +17 -6
  108. package/src/logger.ts +291 -121
  109. package/src/mockLogger.ts +65 -24
  110. package/src/sampledTelemetryHelper.ts +20 -16
  111. package/src/telemetryTypes.ts +29 -6
  112. package/src/thresholdCounter.ts +2 -2
  113. package/src/utils.ts +3 -3
  114. package/dist/debugLogger.d.ts +0 -39
  115. package/dist/debugLogger.d.ts.map +0 -1
  116. package/dist/debugLogger.js +0 -112
  117. package/dist/debugLogger.js.map +0 -1
  118. package/lib/debugLogger.d.ts +0 -39
  119. package/lib/debugLogger.d.ts.map +0 -1
  120. package/lib/debugLogger.js +0 -108
  121. package/lib/debugLogger.js.map +0 -1
  122. package/src/debugLogger.ts +0 -143
@@ -5,10 +5,10 @@
5
5
 
6
6
  import {
7
7
  ILoggingError,
8
- ITaggedTelemetryPropertyType,
9
- ITelemetryProperties,
10
- TelemetryEventPropertyType,
11
- } from "@fluidframework/common-definitions";
8
+ ITelemetryBaseProperties,
9
+ TelemetryBaseEventPropertyType,
10
+ Tagged,
11
+ } from "@fluidframework/core-interfaces";
12
12
  import { v4 as uuid } from "uuid";
13
13
  import {
14
14
  hasErrorInstanceId,
@@ -16,20 +16,27 @@ import {
16
16
  isFluidError,
17
17
  isValidLegacyError,
18
18
  } from "./fluidErrorBase";
19
- import {
20
- ITaggedTelemetryPropertyTypeExt,
21
- ITelemetryLoggerExt,
22
- TelemetryEventPropertyTypeExt,
23
- } from "./telemetryTypes";
19
+ import { ITelemetryLoggerExt, TelemetryEventPropertyTypeExt } from "./telemetryTypes";
24
20
 
25
- /** @returns true if value is an object but neither null nor an array */
26
- const isRegularObject = (value: any): boolean => {
21
+ /**
22
+ * Determines if the provided value is an object but neither null nor an array.
23
+ */
24
+ const isRegularObject = (value: unknown): boolean => {
27
25
  return value !== null && !Array.isArray(value) && typeof value === "object";
28
26
  };
29
27
 
30
- /** Inspect the given error for common "safe" props and return them */
31
- export function extractLogSafeErrorProperties(error: any, sanitizeStack: boolean) {
32
- const removeMessageFromStack = (stack: string, errorName?: string) => {
28
+ /**
29
+ * Inspect the given error for common "safe" props and return them.
30
+ */
31
+ export function extractLogSafeErrorProperties(
32
+ error: unknown,
33
+ sanitizeStack: boolean,
34
+ ): {
35
+ message: string;
36
+ errorType?: string | undefined;
37
+ stack?: string | undefined;
38
+ } {
39
+ const removeMessageFromStack = (stack: string, errorName?: string): string => {
33
40
  if (!sanitizeStack) {
34
41
  return stack;
35
42
  }
@@ -41,14 +48,17 @@ export function extractLogSafeErrorProperties(error: any, sanitizeStack: boolean
41
48
  return stackFrames.join("\n");
42
49
  };
43
50
 
44
- const message = typeof error?.message === "string" ? (error.message as string) : String(error);
51
+ const message =
52
+ typeof (error as Partial<Error>)?.message === "string"
53
+ ? (error as Error).message
54
+ : String(error);
45
55
 
46
56
  const safeProps: { message: string; errorType?: string; stack?: string } = {
47
57
  message,
48
58
  };
49
59
 
50
60
  if (isRegularObject(error)) {
51
- const { errorType, stack, name } = error;
61
+ const { errorType, stack, name } = error as Partial<IFluidErrorBase>;
52
62
 
53
63
  if (typeof errorType === "string") {
54
64
  safeProps.errorType = errorType;
@@ -63,12 +73,19 @@ export function extractLogSafeErrorProperties(error: any, sanitizeStack: boolean
63
73
  return safeProps;
64
74
  }
65
75
 
66
- /** type guard for ILoggingError interface */
67
- export const isILoggingError = (x: any): x is ILoggingError =>
68
- typeof x?.getTelemetryProperties === "function";
76
+ /**
77
+ * type guard for ILoggingError interface
78
+ */
79
+ export const isILoggingError = (x: unknown): x is ILoggingError =>
80
+ typeof (x as Partial<ILoggingError>)?.getTelemetryProperties === "function";
69
81
 
70
- /** Copy props from source onto target, but do not overwrite an existing prop that matches */
71
- function copyProps(target: ITelemetryProperties | LoggingError, source: ITelemetryProperties) {
82
+ /**
83
+ * Copy props from source onto target, but do not overwrite an existing prop that matches
84
+ */
85
+ function copyProps(
86
+ target: ITelemetryBaseProperties | LoggingError,
87
+ source: ITelemetryBaseProperties,
88
+ ): void {
72
89
  for (const key of Object.keys(source)) {
73
90
  if (target[key] === undefined) {
74
91
  target[key] = source[key];
@@ -76,16 +93,23 @@ function copyProps(target: ITelemetryProperties | LoggingError, source: ITelemet
76
93
  }
77
94
  }
78
95
 
79
- /** Metadata to annotate an error object when annotating or normalizing it */
96
+ /**
97
+ * Metadata to annotate an error object when annotating or normalizing it
98
+ */
80
99
  export interface IFluidErrorAnnotations {
81
- /** Telemetry props to log with the error */
82
- props?: ITelemetryProperties;
100
+ /**
101
+ * Telemetry props to log with the error
102
+ */
103
+ props?: ITelemetryBaseProperties;
83
104
  }
84
105
 
85
- /** For backwards compatibility with pre-errorInstanceId valid errors */
106
+ /**
107
+ * For backwards compatibility with pre-errorInstanceId valid errors
108
+ */
86
109
  function patchLegacyError(
87
110
  legacyError: Omit<IFluidErrorBase, "errorInstanceId">,
88
111
  ): asserts legacyError is IFluidErrorBase {
112
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-explicit-any
89
113
  const patchMe: { -readonly [P in "errorInstanceId"]?: IFluidErrorBase[P] } = legacyError as any;
90
114
  if (patchMe.errorInstanceId === undefined) {
91
115
  patchMe.errorInstanceId = uuid();
@@ -180,8 +204,8 @@ export function generateErrorWithStack(): Error {
180
204
 
181
205
  try {
182
206
  throw err;
183
- } catch (e) {
184
- return e as Error;
207
+ } catch (error) {
208
+ return error as Error;
185
209
  }
186
210
  }
187
211
 
@@ -230,12 +254,16 @@ export function wrapError<T extends LoggingError>(
230
254
  return newError;
231
255
  }
232
256
 
233
- /** The same as wrapError, but also logs the innerError, including the wrapping error's instance id */
257
+ /**
258
+ * The same as wrapError, but also logs the innerError, including the wrapping error's instance ID.
259
+ *
260
+ * @typeParam T - The kind of wrapper error to create.
261
+ */
234
262
  export function wrapErrorAndLog<T extends LoggingError>(
235
263
  innerError: unknown,
236
264
  newErrorFn: (message: string) => T,
237
265
  logger: ITelemetryLoggerExt,
238
- ) {
266
+ ): T {
239
267
  const newError = wrapError(innerError, newErrorFn);
240
268
 
241
269
  // This will match innerError.errorInstanceId if present (see wrapError)
@@ -256,11 +284,18 @@ export function wrapErrorAndLog<T extends LoggingError>(
256
284
  return newError;
257
285
  }
258
286
 
259
- function overwriteStack(error: IFluidErrorBase | LoggingError, stack: string) {
260
- // supposedly setting stack on an Error can throw.
287
+ /**
288
+ * Attempts to overwrite the error's stack
289
+ *
290
+ * There have been reports of certain JS environments where overwriting stack will throw.
291
+ * If that happens, this adds the given stack as the telemetry property "stack2"
292
+ *
293
+ * @internal
294
+ */
295
+ export function overwriteStack(error: IFluidErrorBase | LoggingError, stack: string): void {
261
296
  try {
262
297
  Object.assign(error, { stack });
263
- } catch (errorSettingStack) {
298
+ } catch {
264
299
  error.addTelemetryProperties({ stack2: stack });
265
300
  }
266
301
  }
@@ -270,35 +305,35 @@ function overwriteStack(error: IFluidErrorBase | LoggingError, stack: string) {
270
305
  * False for any error we created and raised within the FF codebase via LoggingError base class,
271
306
  * or wrapped in a well-known error type
272
307
  */
273
- export function isExternalError(e: any): boolean {
308
+ export function isExternalError(error: unknown): boolean {
274
309
  // LoggingErrors are an internal FF error type. However, an external error can be converted
275
310
  // into a LoggingError if it is normalized. In this case we must use the untrustedOrigin flag to
276
311
  // determine whether the original error was infact external.
277
- if (LoggingError.typeCheck(e)) {
278
- if ((e as NormalizedLoggingError).errorType === NORMALIZED_ERROR_TYPE) {
279
- return e.getTelemetryProperties().untrustedOrigin === 1;
312
+ if (LoggingError.typeCheck(error)) {
313
+ if ((error as NormalizedLoggingError).errorType === NORMALIZED_ERROR_TYPE) {
314
+ return error.getTelemetryProperties().untrustedOrigin === 1;
280
315
  }
281
316
  return false;
282
317
  }
283
- return !isValidLegacyError(e);
318
+ return !isValidLegacyError(error);
284
319
  }
285
320
 
286
321
  /**
287
322
  * Type guard to identify if a particular telemetry property appears to be a tagged telemetry property
288
323
  */
289
324
  export function isTaggedTelemetryPropertyValue(
290
- x: ITaggedTelemetryPropertyTypeExt | TelemetryEventPropertyTypeExt,
291
- ): x is ITaggedTelemetryPropertyType | ITaggedTelemetryPropertyTypeExt {
292
- return typeof (x as any)?.tag === "string";
325
+ x: Tagged<TelemetryEventPropertyTypeExt> | TelemetryEventPropertyTypeExt,
326
+ ): x is Tagged<TelemetryEventPropertyTypeExt> {
327
+ return typeof (x as Partial<Tagged<unknown>>)?.tag === "string";
293
328
  }
294
329
 
295
330
  /**
296
331
  * Filter serializable telemetry properties
297
- * @param x - any telemetry prop
298
- * @returns - as-is if x is primitive. returns stringified if x is an array of primitive.
332
+ * @param x - Any telemetry prop
333
+ * @returns As-is if x is primitive. returns stringified if x is an array of primitive.
299
334
  * otherwise returns null since this is what we support at the moment.
300
335
  */
301
- function filterValidTelemetryProps(x: any, key: string): TelemetryEventPropertyType {
336
+ function filterValidTelemetryProps(x: unknown, key: string): TelemetryBaseEventPropertyType {
302
337
  if (Array.isArray(x) && x.every((val) => isTelemetryEventPropertyValue(val))) {
303
338
  return JSON.stringify(x);
304
339
  }
@@ -311,7 +346,7 @@ function filterValidTelemetryProps(x: any, key: string): TelemetryEventPropertyT
311
346
  }
312
347
 
313
348
  // checking type of x, returns false if x is null
314
- function isTelemetryEventPropertyValue(x: any): x is TelemetryEventPropertyType {
349
+ function isTelemetryEventPropertyValue(x: unknown): x is TelemetryBaseEventPropertyType {
315
350
  switch (typeof x) {
316
351
  case "string":
317
352
  case "number":
@@ -325,13 +360,15 @@ function isTelemetryEventPropertyValue(x: any): x is TelemetryEventPropertyType
325
360
  /**
326
361
  * Walk an object's enumerable properties to find those fit for telemetry.
327
362
  */
328
- function getValidTelemetryProps(obj: any, keysToOmit: Set<string>): ITelemetryProperties {
329
- const props: ITelemetryProperties = {};
363
+ function getValidTelemetryProps(obj: object, keysToOmit: Set<string>): ITelemetryBaseProperties {
364
+ const props: ITelemetryBaseProperties = {};
330
365
  for (const key of Object.keys(obj)) {
331
366
  if (keysToOmit.has(key)) {
332
367
  continue;
333
368
  }
334
- const val = obj[key];
369
+ const val = obj[key] as
370
+ | TelemetryEventPropertyTypeExt
371
+ | Tagged<TelemetryEventPropertyTypeExt>;
335
372
 
336
373
  // ensure only valid props get logged, since props of logging error could be in any shape
337
374
  if (isTaggedTelemetryPropertyValue(val)) {
@@ -353,9 +390,11 @@ function getValidTelemetryProps(obj: any, keysToOmit: Set<string>): ITelemetryPr
353
390
  * Not ideal, as will cut values that are not necessarily circular references.
354
391
  * Could be improved by implementing Node's util.inspect() for browser (minus all the coloring code)
355
392
  */
356
- export const getCircularReplacer = () => {
393
+ // TODO: Use `unknown` instead (API breaking change)
394
+ /* eslint-disable @typescript-eslint/no-explicit-any */
395
+ export const getCircularReplacer = (): ((key: string, value: unknown) => any) => {
357
396
  const seen = new WeakSet();
358
- return (key: string, value: any): any => {
397
+ return (key: string, value: unknown): any => {
359
398
  if (typeof value === "object" && value !== null) {
360
399
  if (seen.has(value)) {
361
400
  return "<removed/circular>";
@@ -365,6 +404,7 @@ export const getCircularReplacer = () => {
365
404
  return value;
366
405
  };
367
406
  };
407
+ /* eslint-enable @typescript-eslint/no-explicit-any */
368
408
 
369
409
  /**
370
410
  * Base class for "trusted" errors we create, whose properties can generally be logged to telemetry safely.
@@ -378,15 +418,18 @@ export class LoggingError
378
418
  implements ILoggingError, Omit<IFluidErrorBase, "errorType">
379
419
  {
380
420
  private _errorInstanceId = uuid();
381
- get errorInstanceId() {
421
+ get errorInstanceId(): string {
382
422
  return this._errorInstanceId;
383
423
  }
384
- overwriteErrorInstanceId(id: string) {
424
+ overwriteErrorInstanceId(id: string): void {
385
425
  this._errorInstanceId = id;
386
426
  }
387
427
 
388
- /** Back-compat to appease isFluidError typeguard in old code that may handle this error */
428
+ /**
429
+ * Backwards compatibility to appease {@link isFluidError} in old code that may handle this error.
430
+ */
389
431
  // @ts-expect-error - This field shouldn't be referenced in the current version, but needs to exist at runtime.
432
+ // eslint-disable-next-line @typescript-eslint/prefer-as-const
390
433
  private readonly fluidErrorCode: "-" = "-";
391
434
 
392
435
  /**
@@ -397,7 +440,7 @@ export class LoggingError
397
440
  */
398
441
  constructor(
399
442
  message: string,
400
- props?: ITelemetryProperties,
443
+ props?: ITelemetryBaseProperties,
401
444
  private readonly omitPropsFromLogging: Set<string> = new Set(),
402
445
  ) {
403
446
  super(message);
@@ -414,7 +457,7 @@ export class LoggingError
414
457
  /**
415
458
  * Determines if a given object is an instance of a LoggingError
416
459
  * @param object - any object
417
- * @returns - true if the object is an instance of a LoggingError, false if not.
460
+ * @returns true if the object is an instance of a LoggingError, false if not.
418
461
  */
419
462
  public static typeCheck(object: unknown): object is LoggingError {
420
463
  if (typeof object === "object" && object !== null) {
@@ -430,14 +473,14 @@ export class LoggingError
430
473
  /**
431
474
  * Add additional properties to be logged
432
475
  */
433
- public addTelemetryProperties(props: ITelemetryProperties) {
476
+ public addTelemetryProperties(props: ITelemetryBaseProperties): void {
434
477
  copyProps(this, props);
435
478
  }
436
479
 
437
480
  /**
438
481
  * Get all properties fit to be logged to telemetry for this error
439
482
  */
440
- public getTelemetryProperties(): ITelemetryProperties {
483
+ public getTelemetryProperties(): ITelemetryBaseProperties {
441
484
  const taggableProps = getValidTelemetryProps(this, this.omitPropsFromLogging);
442
485
  // Include non-enumerable props that are not returned by getValidTelemetryProps
443
486
  return {
@@ -449,7 +492,9 @@ export class LoggingError
449
492
  }
450
493
  }
451
494
 
452
- /** The Error class used when normalizing an external error */
495
+ /**
496
+ * The Error class used when normalizing an external error
497
+ */
453
498
  export const NORMALIZED_ERROR_TYPE = "genericError";
454
499
  class NormalizedLoggingError extends LoggingError {
455
500
  // errorType "genericError" is used as a default value throughout the code.
@@ -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 { IEvent } from "@fluidframework/common-definitions";
6
- import { TypedEventEmitter, EventEmitterEventType } from "@fluidframework/common-utils";
5
+ import { TypedEventEmitter, EventEmitterEventType } from "@fluid-internal/client-utils";
6
+ import { IEvent } from "@fluidframework/core-interfaces";
7
7
 
8
8
  /**
9
9
  * Event Emitter helper class
@@ -14,12 +14,14 @@ export class EventEmitterWithErrorHandling<
14
14
  TEvent extends IEvent = IEvent,
15
15
  > extends TypedEventEmitter<TEvent> {
16
16
  constructor(
17
+ // TODO: use `unknown` instead (breaking API change)
18
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
19
  private readonly errorHandler: (eventName: EventEmitterEventType, error: any) => void,
18
20
  ) {
19
21
  super();
20
22
  }
21
23
 
22
- public emit(event: EventEmitterEventType, ...args: any[]): boolean {
24
+ public emit(event: EventEmitterEventType, ...args: unknown[]): boolean {
23
25
  try {
24
26
  return super.emit(event, ...args);
25
27
  } catch (error) {
package/src/events.ts CHANGED
@@ -13,8 +13,8 @@ export function safeRaiseEvent(
13
13
  emitter: EventEmitter,
14
14
  logger: ITelemetryLoggerExt,
15
15
  event: string,
16
- ...args
17
- ) {
16
+ ...args: unknown[]
17
+ ): void {
18
18
  try {
19
19
  emitter.emit(event, ...args);
20
20
  } catch (error) {
@@ -36,7 +36,7 @@ export function raiseConnectedEvent(
36
36
  connected: boolean,
37
37
  clientId?: string,
38
38
  disconnectedReason?: string,
39
- ) {
39
+ ): void {
40
40
  try {
41
41
  if (connected) {
42
42
  emitter.emit(connectedEventName, clientId);
@@ -3,65 +3,101 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { ITelemetryProperties } from "@fluidframework/common-definitions";
6
+ import { ITelemetryProperties } from "@fluidframework/core-interfaces";
7
7
 
8
8
  /**
9
+ * An error emitted by the Fluid Framework.
10
+ *
11
+ * @remarks
12
+ *
9
13
  * All normalized errors flowing through the Fluid Framework adhere to this readonly interface.
10
- * It features errorType and errorInstanceId on top of Error's members as readonly,
11
- * and a getter/setter for telemetry props to be included when the error is logged.
14
+ *
15
+ * It features the members of {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error | Error}
16
+ * made readonly, as well as {@link IFluidErrorBase.errorType} and {@link IFluidErrorBase.errorInstanceId}.
17
+ * It also features getters and setters for telemetry props to be included when the error is logged.
12
18
  */
13
19
  export interface IFluidErrorBase extends Error {
14
- /** Classification of what type of error this is, used programmatically by consumers to interpret the error */
20
+ /**
21
+ * Classification of what type of error this is.
22
+ *
23
+ * @remarks Used programmatically by consumers to interpret the error.
24
+ */
15
25
  readonly errorType: string;
16
26
 
17
27
  /**
18
28
  * Error's message property, made readonly.
19
- * Be specific, but also take care when including variable data to consider suitability for aggregation in telemetry
20
- * Also avoid including any data that jeopardizes the user's privacy. Add a tagged telemetry property instead.
29
+ *
30
+ * @remarks
31
+ *
32
+ * Recommendations:
33
+ *
34
+ * Be specific, but also take care when including variable data to consider suitability for aggregation in telemetry.
35
+ * Also avoid including any data that jeopardizes the user's privacy. Add a tagged telemetry property instead.
21
36
  */
22
37
  readonly message: string;
23
38
 
24
- /** Error's stack property, made readonly */
39
+ /**
40
+ * See {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/stack}.
41
+ */
25
42
  readonly stack?: string;
26
43
 
27
- /** Error's name property, made readonly */
44
+ /**
45
+ * See {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/name}.
46
+ */
28
47
  readonly name: string;
29
48
 
30
49
  /**
31
50
  * A Guid identifying this error instance.
32
- * Useful in telemetry for deduping multiple logging events arising from the same error,
51
+ *
52
+ * @remarks
53
+ *
54
+ * Useful in telemetry for deduplicating multiple logging events arising from the same error,
33
55
  * or correlating an error with an inner error that caused it, in case of error wrapping.
34
56
  */
35
57
  readonly errorInstanceId: string;
36
58
 
37
- /** Get the telemetry properties stashed on this error for logging */
59
+ /**
60
+ * Get the telemetry properties stashed on this error for logging.
61
+ */
38
62
  getTelemetryProperties(): ITelemetryProperties;
39
- /** Add telemetry properties to this error which will be logged with the error */
63
+
64
+ /**
65
+ * Add telemetry properties to this error which will be logged with the error
66
+ */
40
67
  addTelemetryProperties: (props: ITelemetryProperties) => void;
41
68
  }
42
69
 
43
- const hasTelemetryPropFunctions = (x: any): boolean =>
44
- typeof x?.getTelemetryProperties === "function" &&
45
- typeof x?.addTelemetryProperties === "function";
70
+ const hasTelemetryPropFunctions = (x: unknown): boolean =>
71
+ typeof (x as Partial<IFluidErrorBase>)?.getTelemetryProperties === "function" &&
72
+ typeof (x as Partial<IFluidErrorBase>)?.addTelemetryProperties === "function";
46
73
 
47
- export const hasErrorInstanceId = (x: any): x is { errorInstanceId: string } =>
48
- typeof x?.errorInstanceId === "string";
74
+ /**
75
+ * Type guard for error data containing the {@link IFluidErrorBase.errorInstanceId} property.
76
+ */
77
+ export const hasErrorInstanceId = (x: unknown): x is { errorInstanceId: string } =>
78
+ typeof (x as Partial<{ errorInstanceId: string }>)?.errorInstanceId === "string";
49
79
 
50
- /** type guard for IFluidErrorBase interface */
51
- export function isFluidError(e: any): e is IFluidErrorBase {
80
+ /**
81
+ * Type guard for {@link IFluidErrorBase}.
82
+ */
83
+ export function isFluidError(error: unknown): error is IFluidErrorBase {
52
84
  return (
53
- typeof e?.errorType === "string" &&
54
- typeof e?.message === "string" &&
55
- hasErrorInstanceId(e) &&
56
- hasTelemetryPropFunctions(e)
85
+ typeof (error as Partial<IFluidErrorBase>)?.errorType === "string" &&
86
+ typeof (error as Partial<IFluidErrorBase>)?.message === "string" &&
87
+ hasErrorInstanceId(error) &&
88
+ hasTelemetryPropFunctions(error)
57
89
  );
58
90
  }
59
91
 
60
- /** type guard for old standard of valid/known errors */
61
- export function isValidLegacyError(e: any): e is Omit<IFluidErrorBase, "errorInstanceId"> {
92
+ /**
93
+ * Type guard for old standard of valid/known errors.
94
+ */
95
+ export function isValidLegacyError(
96
+ error: unknown,
97
+ ): error is Omit<IFluidErrorBase, "errorInstanceId"> {
62
98
  return (
63
- typeof e?.errorType === "string" &&
64
- typeof e?.message === "string" &&
65
- hasTelemetryPropFunctions(e)
99
+ typeof (error as Partial<IFluidErrorBase>)?.errorType === "string" &&
100
+ typeof (error as Partial<IFluidErrorBase>)?.message === "string" &&
101
+ hasTelemetryPropFunctions(error)
66
102
  );
67
103
  }
package/src/index.ts CHANGED
@@ -3,6 +3,7 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
  export {
6
+ createChildMonitoringContext,
6
7
  MonitoringContext,
7
8
  IConfigProviderBase,
8
9
  sessionStorageConfigProvider,
@@ -11,7 +12,13 @@ export {
11
12
  ConfigTypes,
12
13
  loggerToMonitoringContext,
13
14
  } from "./config";
14
- export { DebugLogger } from "./debugLogger";
15
+ export {
16
+ DataCorruptionError,
17
+ DataProcessingError,
18
+ extractSafePropertiesFromMessage,
19
+ GenericError,
20
+ UsageError,
21
+ } from "./error";
15
22
  export {
16
23
  extractLogSafeErrorProperties,
17
24
  generateErrorWithStack,
@@ -24,6 +31,7 @@ export {
24
31
  LoggingError,
25
32
  NORMALIZED_ERROR_TYPE,
26
33
  normalizeError,
34
+ overwriteStack,
27
35
  wrapError,
28
36
  wrapErrorAndLog,
29
37
  } from "./errorLogging";
@@ -41,19 +49,21 @@ export {
41
49
  isValidLegacyError,
42
50
  } from "./fluidErrorBase";
43
51
  export {
44
- BaseTelemetryNullLogger,
45
- ChildLogger,
52
+ eventNamespaceSeparator,
53
+ createChildLogger,
54
+ createMultiSinkLogger,
55
+ formatTick,
46
56
  IPerformanceEventMarkers,
47
57
  ITelemetryLoggerPropertyBag,
48
58
  ITelemetryLoggerPropertyBags,
49
- MultiSinkLogger,
59
+ numberFromString,
50
60
  PerformanceEvent,
51
61
  TaggedLoggerAdapter,
62
+ tagData,
63
+ tagCodeArtifacts,
52
64
  TelemetryDataTag,
53
65
  TelemetryEventPropertyTypes,
54
- TelemetryLogger,
55
66
  TelemetryNullLogger,
56
- TelemetryUTLogger,
57
67
  } from "./logger";
58
68
  export { MockLogger } from "./mockLogger";
59
69
  export { ThresholdCounter } from "./thresholdCounter";
@@ -68,4 +78,5 @@ export {
68
78
  ITelemetryLoggerExt,
69
79
  ITaggedTelemetryPropertyTypeExt,
70
80
  ITelemetryPropertiesExt,
81
+ TelemetryEventCategory,
71
82
  } from "./telemetryTypes";