From 38d93e23a55af4c2e95dd4ba68a2a6a512fb0948 Mon Sep 17 00:00:00 2001 From: Ayush Pahwa Date: Fri, 30 Sep 2022 18:29:02 +0530 Subject: [PATCH] fix: console log dx issue fixes (#17137) * chore: moved all helpers and types to diff files * fix: cloning the incoming object to avoid mutation --- .../editorComponents/Debugger/helpers.tsx | 52 ++++++++++++ .../src/entities/AppsmithConsole/index.ts | 24 ++++++ app/client/src/sagas/DebuggerSagas.ts | 7 +- app/client/src/sagas/EvaluationsSaga.ts | 7 +- .../src/workers/DataTreeEvaluator/index.ts | 2 +- app/client/src/workers/UserLog.ts | 83 ++----------------- app/client/src/workers/evaluate.ts | 4 +- app/client/src/workers/evaluation.worker.ts | 2 +- 8 files changed, 95 insertions(+), 86 deletions(-) diff --git a/app/client/src/components/editorComponents/Debugger/helpers.tsx b/app/client/src/components/editorComponents/Debugger/helpers.tsx index dd38f97fcc..ad82747ce8 100644 --- a/app/client/src/components/editorComponents/Debugger/helpers.tsx +++ b/app/client/src/components/editorComponents/Debugger/helpers.tsx @@ -65,6 +65,58 @@ export const SeverityIcon: Record = { [Severity.WARNING]: "warning", }; +const truncate = (input: string, suffix = "", truncLen = 100) => { + try { + if (!!input) { + return input.length > truncLen + ? `${input.substring(0, truncLen)}...${suffix}` + : input; + } else { + return ""; + } + } catch (error) { + return `Invalid log: ${JSON.stringify(error)}`; + } +}; + +// Converts the data from the log object to a string +export function createLogTitleString(data: any[]) { + try { + // convert mixed array to string + return data.reduce((acc, curr) => { + // curr can be a string or an object + if (typeof curr === "boolean") { + return `${acc} ${curr}`; + } + if (curr === null || curr === undefined) { + return `${acc} undefined`; + } + if (curr instanceof Promise) { + return `${acc} Promise ${curr.constructor.name}`; + } + if (typeof curr === "string") { + return `${acc} ${truncate(curr)}`; + } + if (typeof curr === "number") { + return `${acc} ${truncate(curr.toString())}`; + } + if (typeof curr === "function") { + return `${acc} func() ${curr.name}`; + } + if (typeof curr === "object") { + let suffix = "}"; + if (Array.isArray(curr)) { + suffix = "]"; + } + return `${acc} ${truncate(JSON.stringify(curr, null, "\t"), suffix)}`; + } + acc = `${acc} -`; + }, ""); + } catch (error) { + return `Error in parsing log: ${JSON.stringify(error)}`; + } +} + export const getLogIcon = (log: Log) => { if (log.severity === Severity.ERROR) { return SeverityIcon[log.severity]; diff --git a/app/client/src/entities/AppsmithConsole/index.ts b/app/client/src/entities/AppsmithConsole/index.ts index 8602d739c6..e8ba4d4955 100644 --- a/app/client/src/entities/AppsmithConsole/index.ts +++ b/app/client/src/entities/AppsmithConsole/index.ts @@ -14,6 +14,30 @@ export enum PLATFORM_ERROR { JS_FUNCTION_EXECUTION = "JS_FUNCTION_EXECUTION", } +export type Methods = + | "log" + | "debug" + | "info" + | "warn" + | "error" + | "table" + | "clear" + | "time" + | "timeEnd" + | "count" + | "assert"; + +export type UserLogObject = { logObject: LogObject[]; source: SourceEntity }; + +// Type of the log object +export type LogObject = { + method: Methods | "result"; + data: any[]; + timestamp: string; + id: string; + severity: Severity; +}; + export type ErrorType = PropertyEvaluationErrorType | PLATFORM_ERROR; export enum Severity { diff --git a/app/client/src/sagas/DebuggerSagas.ts b/app/client/src/sagas/DebuggerSagas.ts index 78a15bf9b4..82a608f8c9 100644 --- a/app/client/src/sagas/DebuggerSagas.ts +++ b/app/client/src/sagas/DebuggerSagas.ts @@ -13,6 +13,7 @@ import { ENTITY_TYPE, Log, LogActionPayload, + LogObject, LOG_CATEGORY, } from "entities/AppsmithConsole"; import { @@ -44,7 +45,10 @@ import { isAction, isWidget, } from "workers/evaluationUtils"; -import { getDependencyChain } from "components/editorComponents/Debugger/helpers"; +import { + createLogTitleString, + getDependencyChain, +} from "components/editorComponents/Debugger/helpers"; import { ACTION_CONFIGURATION_UPDATED, createMessage, @@ -58,7 +62,6 @@ import { getCurrentPageId } from "selectors/editorSelectors"; import { WidgetProps } from "widgets/BaseWidget"; import * as log from "loglevel"; import { DependencyMap } from "utils/DynamicBindingUtils"; -import { LogObject, createLogTitleString } from "workers/UserLog"; import { TriggerMeta } from "./ActionExecution/ActionExecutionSagas"; // Saga to format action request values to be shown in the debugger diff --git a/app/client/src/sagas/EvaluationsSaga.ts b/app/client/src/sagas/EvaluationsSaga.ts index e166124df9..cb3249fda1 100644 --- a/app/client/src/sagas/EvaluationsSaga.ts +++ b/app/client/src/sagas/EvaluationsSaga.ts @@ -78,7 +78,11 @@ import { diff } from "deep-diff"; import { REPLAY_DELAY } from "entities/Replay/replayUtils"; import { EvaluationVersion } from "api/ApplicationApi"; import { makeUpdateJSCollection } from "sagas/JSPaneSagas"; -import { ENTITY_TYPE } from "entities/AppsmithConsole"; +import { + ENTITY_TYPE, + LogObject, + UserLogObject, +} from "entities/AppsmithConsole"; import { Replayable } from "entities/Replay/ReplayEntity/ReplayEditor"; import { logActionExecutionError, @@ -98,7 +102,6 @@ import { DataTreeDiff } from "workers/evaluationUtils"; import { CanvasWidgetsReduxState } from "reducers/entityReducers/canvasWidgetsReducer"; import { AppTheme } from "entities/AppTheming"; import { ActionValidationConfigMap } from "constants/PropertyControlConstants"; -import { LogObject, UserLogObject } from "workers/UserLog"; import { storeLogs, updateTriggerMeta } from "./DebuggerSagas"; let widgetTypeConfigMap: WidgetTypeConfigMap; diff --git a/app/client/src/workers/DataTreeEvaluator/index.ts b/app/client/src/workers/DataTreeEvaluator/index.ts index 171969454a..854cb5b190 100644 --- a/app/client/src/workers/DataTreeEvaluator/index.ts +++ b/app/client/src/workers/DataTreeEvaluator/index.ts @@ -63,6 +63,7 @@ import { Severity, SourceEntity, ENTITY_TYPE as CONSOLE_ENTITY_TYPE, + UserLogObject, } from "entities/AppsmithConsole"; import { error as logError } from "loglevel"; import { JSUpdate } from "utils/JSPaneUtils"; @@ -83,7 +84,6 @@ import { parseJSActions, } from "workers/JSObject"; import { lintTree } from "workers/Lint"; -import { UserLogObject } from "workers/UserLog"; export default class DataTreeEvaluator { dependencyMap: DependencyMap = {}; diff --git a/app/client/src/workers/UserLog.ts b/app/client/src/workers/UserLog.ts index b017b3f690..68067a0b63 100644 --- a/app/client/src/workers/UserLog.ts +++ b/app/client/src/workers/UserLog.ts @@ -1,83 +1,8 @@ import { uuid4 } from "@sentry/utils"; -import { Severity, SourceEntity } from "entities/AppsmithConsole"; +import { LogObject, Methods, Severity } from "entities/AppsmithConsole"; +import { klona } from "klona/lite"; import moment from "moment"; -export type Methods = - | "log" - | "debug" - | "info" - | "warn" - | "error" - | "table" - | "clear" - | "time" - | "timeEnd" - | "count" - | "assert"; - -export type UserLogObject = { logObject: LogObject[]; source: SourceEntity }; - -// Type of the log object -export type LogObject = { - method: Methods | "result"; - data: any[]; - timestamp: string; - id: string; - severity: Severity; -}; - -const truncate = (input: string, suffix = "", truncLen = 100) => { - try { - if (!!input) { - return input.length > truncLen - ? `${input.substring(0, truncLen)}...${suffix}` - : input; - } else { - return ""; - } - } catch (error) { - return `Invalid log: ${JSON.stringify(error)}`; - } -}; - -// Converts the data from the log object to a string -export function createLogTitleString(data: any[]) { - try { - // convert mixed array to string - return data.reduce((acc, curr) => { - // curr can be a string or an object - if (typeof curr === "boolean") { - return `${acc} ${curr}`; - } - if (curr === null || curr === undefined) { - return `${acc} undefined`; - } - if (curr instanceof Promise) { - return `${acc} Promise ${curr.constructor.name}`; - } - if (typeof curr === "string") { - return `${acc} ${truncate(curr)}`; - } - if (typeof curr === "number") { - return `${acc} ${truncate(curr.toString())}`; - } - if (typeof curr === "function") { - return `${acc} func() ${curr.name}`; - } - if (typeof curr === "object") { - let suffix = "}"; - if (Array.isArray(curr)) { - suffix = "]"; - } - return `${acc} ${truncate(JSON.stringify(curr, null, "\t"), suffix)}`; - } - acc = `${acc} -`; - }, ""); - } catch (error) { - return `Error in parsing log: ${JSON.stringify(error)}`; - } -} - class UserLog { constructor() { this.initiate(); @@ -160,7 +85,9 @@ class UserLog { let returnData = []; try { - returnData = data.map((item: any) => { + // cloning the object to avoid mutation + const dataObject = klona(data); + returnData = dataObject.map((item: any) => { if (typeof item === "object") { return this.replaceFunctionWithNamesFromObjects(item); } diff --git a/app/client/src/workers/evaluate.ts b/app/client/src/workers/evaluate.ts index 0bcb72b504..9ebec6f801 100644 --- a/app/client/src/workers/evaluate.ts +++ b/app/client/src/workers/evaluate.ts @@ -7,12 +7,12 @@ import { unsafeFunctionForEval, } from "utils/DynamicBindingUtils"; import unescapeJS from "unescape-js"; -import { Severity } from "entities/AppsmithConsole"; +import { LogObject, Severity } from "entities/AppsmithConsole"; import { enhanceDataTreeWithFunctions } from "./Actions"; import { isEmpty } from "lodash"; import { completePromise } from "workers/PromisifyAction"; import { ActionDescription } from "entities/DataTree/actionTriggers"; -import userLogs, { LogObject } from "./UserLog"; +import userLogs from "./UserLog"; export type EvalResult = { result: any; diff --git a/app/client/src/workers/evaluation.worker.ts b/app/client/src/workers/evaluation.worker.ts index 1cfc8d1cb1..a2db3db748 100644 --- a/app/client/src/workers/evaluation.worker.ts +++ b/app/client/src/workers/evaluation.worker.ts @@ -26,7 +26,7 @@ import { setFormEvaluationSaga } from "./formEval"; import { isEmpty } from "lodash"; import { EvalMetaUpdates } from "./DataTreeEvaluator/types"; import { EvalTreePayload } from "../sagas/EvaluationsSaga"; -import { UserLogObject } from "./UserLog"; +import { UserLogObject } from "entities/AppsmithConsole"; const CANVAS = "canvas";