diff --git a/packages/core/src/features/telemetry/renderer/telemetry-decorator.injectable.ts b/packages/core/src/features/telemetry/renderer/telemetry-decorator.injectable.ts index 4b69937367..82cf332b4d 100644 --- a/packages/core/src/features/telemetry/renderer/telemetry-decorator.injectable.ts +++ b/packages/core/src/features/telemetry/renderer/telemetry-decorator.injectable.ts @@ -12,11 +12,18 @@ import { import assert from "assert"; import { isFunction } from "lodash/fp"; -import emitTelemetryInjectable from "./emit-telemetry.injectable"; +import emitTelemetryInjectable, { + EmitTelemetry, +} from "./emit-telemetry.injectable"; import type { WhiteListItem } from "./telemetry-white-list-for-functions.injectable"; import telemetryWhiteListForFunctionsInjectable from "./telemetry-white-list-for-functions.injectable"; -import logErrorInjectable from "../../../common/log-error.injectable"; + +import logErrorInjectable, { + LogError, +} from "../../../common/log-error.injectable"; + +import type { AppEvent } from "../../../common/app-event-bus/event-bus"; const telemetryDecoratorInjectable = getInjectable({ id: "telemetry-decorator", @@ -24,60 +31,39 @@ const telemetryDecoratorInjectable = getInjectable({ instantiate: (diForDecorator) => ({ decorate: (instantiateToBeDecorated: any) => - (di: DiContainerForInjection, instantiationParameter: any) => { - const instance = instantiateToBeDecorated(di, instantiationParameter); + (di: DiContainerForInjection, instantiationParameter: any) => { + const instance = instantiateToBeDecorated(di, instantiationParameter); - if (!isFunction(instance)) { - return instance; + if (!isFunction(instance)) { + return instance; + } + + return (...args: any[]) => { + const currentContext = di.context.at(-1); + + assert(currentContext); + + const emitTelemetry = diForDecorator.inject(emitTelemetryInjectable); + const logError = diForDecorator.inject(logErrorInjectable); + const doTelemetry = doTelemetryFor({ logError, emitTelemetry }); + + const whiteList = diForDecorator.inject( + telemetryWhiteListForFunctionsInjectable + ); + + const whiteListMap = getWhiteListMap(whiteList); + + const whiteListed = whiteListMap.get(currentContext.injectable.id); + + const result = instance(...args); + + if (whiteListed) { + doTelemetry(whiteListed, args, currentContext); } - return (...args: any[]) => { - const currentContext = di.context.at(-1); - - assert(currentContext); - - const emitTelemetry = diForDecorator.inject( - emitTelemetryInjectable - ); - - const logError = diForDecorator.inject(logErrorInjectable); - - const whiteList = diForDecorator.inject( - telemetryWhiteListForFunctionsInjectable - ); - - const whiteListMap = getWhiteListMap(whiteList); - - const whiteListed = whiteListMap.get(currentContext.injectable.id); - - if (!whiteListed) { - return instance(...args); - } - - let params; - - try { - params = whiteListed.getParams(...args); - } catch (e) { - params = { - error: - "Tried to produce params for telemetry, but getParams() threw an error", - }; - - logError( - `Tried to produce params for telemetry of "${currentContext.injectable.id}", but getParams() threw an error`, - e - ); - } - - emitTelemetry({ - action: currentContext.injectable.id, - params, - }); - - return instance(...args); - }; - }, + return result; + }; + }, }), decorable: false, @@ -86,23 +72,60 @@ const telemetryDecoratorInjectable = getInjectable({ injectionToken: instantiationDecoratorToken, }); +const doTelemetryFor = + ({ + logError, + emitTelemetry, + }: { + logError: LogError; + emitTelemetry: EmitTelemetry; + }) => + ( + whiteListed: { getParams: (...args: unknown[]) => AppEvent["params"] }, + args: any[], + currentContext: any + ) => { + try { + const params = whiteListed.getParams(...args); + + emitTelemetry({ + action: currentContext.injectable.id, + params, + }); + } catch (e: any) { + logError( + `Tried to produce params for telemetry of "${currentContext.injectable.id}", but getParams() threw an error`, + e + ); + + emitTelemetry({ + action: currentContext.injectable.id, + + params: { + error: + "Tried to produce params for telemetry, but getParams() threw an error", + }, + }); + } + }; + const getWhiteListMap = (whiteList: WhiteListItem[]) => new Map( whiteList.map((item) => typeof item === "string" ? [ - item, - { - getParams: () => undefined, - }, - ] + item, + { + getParams: () => undefined, + }, + ] : [ - item.id, - { - getParams: item.getParams, - }, - ], - ), + item.id, + { + getParams: item.getParams, + }, + ] + ) ); export default telemetryDecoratorInjectable;