chore: Instrument JS execution (#25613)
This PR adds more details to the "EXECUTE_ACTION" event on trigger fields <img width="500" alt="Screenshot 2023-07-05 at 10 03 32" src="https://github.com/appsmithorg/appsmith/assets/46670083/13b3ab48-6c19-453a-8eb8-c87129e8c8d5"> #### PR fixes following issue(s) Fixes #24706 #### Media > A video or a GIF is preferred. when using Loom, don’t embed because it looks like it’s a GIF. instead, just link to the video > > #### Type of change > Please delete options that are not relevant. - Bug fix (non-breaking change which fixes an issue) - New feature (non-breaking change which adds functionality) - Breaking change (fix or feature that would cause existing functionality to not work as expected) - Chore (housekeeping or task changes that don't impact user perception) - This change requires a documentation update > > > ## Testing > #### How Has This Been Tested? > Please describe the tests that you ran to verify your changes. Also list any relevant details for your test configuration. > Delete anything that is not relevant - [ ] Manual - [ ] Jest - [ ] Cypress > > #### Test Plan > Add Testsmith test cases links that relate to this PR > > #### Issues raised during DP testing > Link issues raised during DP testing for better visiblity and tracking (copy link from comments dropped on this PR) > > > ## Checklist: #### Dev activity - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] PR is being merged under a feature flag #### QA activity: - [ ] [Speedbreak features](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#speedbreakers-) have been covered - [ ] Test plan covers all impacted features and [areas of interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#areas-of-interest-) - [ ] Test plan has been peer reviewed by project stakeholders and other QA members - [ ] Manually tested functionality on DP - [ ] We had an implementation alignment call with stakeholders post QA Round 2 - [ ] Cypress test cases have been added and approved by SDET/manual QA - [ ] Added `Test Plan Approved` label after Cypress tests were reviewed - [ ] Added `Test Plan Approved` label after JUnit tests were reviewed --------- Co-authored-by: Aishwarya UR <aishwarya@appsmith.com>
This commit is contained in:
parent
de66a50f6c
commit
60fa6e352d
|
|
@ -1,3 +1,30 @@
|
|||
export function* logJSFunctionExecution(data: any) {
|
||||
return data;
|
||||
import { TriggerKind } from "constants/AppsmithActionConstants/ActionConstants";
|
||||
import type { TriggerSource } from "constants/AppsmithActionConstants/ActionConstants";
|
||||
import { call } from "redux-saga/effects";
|
||||
import type { TMessage } from "utils/MessageUtil";
|
||||
import { logJSActionExecution } from "./analyticsSaga";
|
||||
|
||||
export function* logJSFunctionExecution(
|
||||
data: TMessage<{
|
||||
data: {
|
||||
jsFnFullName: string;
|
||||
isSuccess: boolean;
|
||||
triggerMeta: {
|
||||
source: TriggerSource;
|
||||
triggerPropertyName: string | undefined;
|
||||
triggerKind: TriggerKind | undefined;
|
||||
};
|
||||
}[];
|
||||
}>,
|
||||
) {
|
||||
const {
|
||||
body: { data: executionData },
|
||||
} = data;
|
||||
|
||||
// We only care about EVENT_EXECUTION
|
||||
const triggerExecutionData = executionData.filter(
|
||||
(execData) =>
|
||||
execData.triggerMeta.triggerKind === TriggerKind.EVENT_EXECUTION,
|
||||
);
|
||||
yield call(logJSActionExecution, triggerExecutionData);
|
||||
}
|
||||
|
|
|
|||
228
app/client/src/ce/sagas/analyticsSaga.ts
Normal file
228
app/client/src/ce/sagas/analyticsSaga.ts
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
import { getCurrentUser } from "selectors/usersSelectors";
|
||||
import { getInstanceId } from "@appsmith/selectors/tenantSelectors";
|
||||
import { getAppsmithConfigs } from "@appsmith/configs";
|
||||
import { call, select } from "redux-saga/effects";
|
||||
import type { APP_MODE } from "entities/App";
|
||||
import {
|
||||
getCurrentApplication,
|
||||
getCurrentPageId,
|
||||
} from "selectors/editorSelectors";
|
||||
import type { TriggerMeta } from "@appsmith/sagas/ActionExecution/ActionExecutionSagas";
|
||||
import type { TriggerSource } from "constants/AppsmithActionConstants/ActionConstants";
|
||||
import { TriggerKind } from "constants/AppsmithActionConstants/ActionConstants";
|
||||
import { isArray } from "lodash";
|
||||
import AnalyticsUtil from "utils/AnalyticsUtil";
|
||||
import { getEntityNameAndPropertyPath } from "@appsmith/workers/Evaluation/evaluationUtils";
|
||||
import { getAppMode, getJSActionFromName } from "selectors/entitiesSelector";
|
||||
import type { AppState } from "@appsmith/reducers";
|
||||
import { getWidget } from "sagas/selectors";
|
||||
|
||||
export function getUserSource() {
|
||||
const { cloudHosting } = getAppsmithConfigs();
|
||||
const source = cloudHosting ? "cloud" : "ce";
|
||||
return source;
|
||||
}
|
||||
|
||||
export interface UserAndAppDetails {
|
||||
pageId: string;
|
||||
appId: string;
|
||||
appMode: APP_MODE | undefined;
|
||||
appName: string;
|
||||
isExampleApp: boolean;
|
||||
userId: string;
|
||||
email: string;
|
||||
source: string;
|
||||
instanceId: string;
|
||||
}
|
||||
|
||||
export function* getUserAndAppDetails() {
|
||||
const appMode: ReturnType<typeof getAppMode> = yield select(getAppMode);
|
||||
const currentApp: ReturnType<typeof getCurrentApplication> = yield select(
|
||||
getCurrentApplication,
|
||||
);
|
||||
const user: ReturnType<typeof getCurrentUser> = yield select(getCurrentUser);
|
||||
const instanceId: ReturnType<typeof getInstanceId> = yield select(
|
||||
getInstanceId,
|
||||
);
|
||||
const pageId: ReturnType<typeof getCurrentPageId> = yield select(
|
||||
getCurrentPageId,
|
||||
);
|
||||
const userAndAppDetails: UserAndAppDetails = {
|
||||
pageId,
|
||||
appId: currentApp?.id || "",
|
||||
appMode,
|
||||
appName: currentApp?.name || "",
|
||||
isExampleApp: currentApp?.appIsExample || false,
|
||||
userId: user?.username || "",
|
||||
email: user?.email || "",
|
||||
source: getUserSource(),
|
||||
instanceId: instanceId,
|
||||
};
|
||||
|
||||
return userAndAppDetails;
|
||||
}
|
||||
export function* logDynamicTriggerExecution({
|
||||
dynamicTrigger,
|
||||
errors,
|
||||
triggerMeta,
|
||||
}: {
|
||||
dynamicTrigger: string;
|
||||
errors: unknown;
|
||||
triggerMeta: TriggerMeta;
|
||||
}) {
|
||||
if (triggerMeta.triggerKind !== TriggerKind.EVENT_EXECUTION) return;
|
||||
const isUnsuccessfulExecution = isArray(errors) && errors.length > 0;
|
||||
const {
|
||||
appId,
|
||||
appMode,
|
||||
appName,
|
||||
email,
|
||||
instanceId,
|
||||
isExampleApp,
|
||||
pageId,
|
||||
source,
|
||||
userId,
|
||||
}: UserAndAppDetails = yield call(getUserAndAppDetails);
|
||||
const widget: ReturnType<typeof getWidget> | undefined = yield select(
|
||||
(state: AppState) => getWidget(state, triggerMeta.source?.id || ""),
|
||||
);
|
||||
|
||||
const dynamicPropertyPathList = widget?.dynamicPropertyPathList;
|
||||
const isJSToggled = !!dynamicPropertyPathList?.find(
|
||||
(property) => property.key === triggerMeta.triggerPropertyName,
|
||||
);
|
||||
AnalyticsUtil.logEvent("EXECUTE_ACTION", {
|
||||
type: "JS_EXPRESSION",
|
||||
unevalValue: dynamicTrigger,
|
||||
pageId,
|
||||
appId,
|
||||
appMode,
|
||||
appName,
|
||||
isExampleApp,
|
||||
userData: {
|
||||
userId,
|
||||
email,
|
||||
appId,
|
||||
source,
|
||||
},
|
||||
widgetName: widget?.widgetName,
|
||||
widgetType: widget?.type,
|
||||
propertyName: triggerMeta.triggerPropertyName,
|
||||
instanceId,
|
||||
isJSToggled,
|
||||
});
|
||||
|
||||
AnalyticsUtil.logEvent(
|
||||
isUnsuccessfulExecution
|
||||
? "EXECUTE_ACTION_FAILURE"
|
||||
: "EXECUTE_ACTION_SUCCESS",
|
||||
{
|
||||
type: "JS_EXPRESSION",
|
||||
unevalValue: dynamicTrigger,
|
||||
pageId,
|
||||
appId,
|
||||
appMode,
|
||||
appName,
|
||||
isExampleApp,
|
||||
userData: {
|
||||
userId,
|
||||
email,
|
||||
appId,
|
||||
source,
|
||||
},
|
||||
widgetName: widget?.widgetName,
|
||||
widgetType: widget?.type,
|
||||
propertyName: triggerMeta.triggerPropertyName,
|
||||
instanceId,
|
||||
isJSToggled,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
export function* logJSActionExecution(
|
||||
executionData: {
|
||||
jsFnFullName: string;
|
||||
isSuccess: boolean;
|
||||
triggerMeta: {
|
||||
source: TriggerSource;
|
||||
triggerPropertyName: string | undefined;
|
||||
triggerKind: TriggerKind | undefined;
|
||||
};
|
||||
}[],
|
||||
) {
|
||||
const {
|
||||
appId,
|
||||
appMode,
|
||||
appName,
|
||||
email,
|
||||
instanceId,
|
||||
isExampleApp,
|
||||
pageId,
|
||||
source,
|
||||
userId,
|
||||
}: UserAndAppDetails = yield call(getUserAndAppDetails);
|
||||
for (const { isSuccess, jsFnFullName, triggerMeta } of executionData) {
|
||||
const { entityName: JSObjectName, propertyPath: functionName } =
|
||||
getEntityNameAndPropertyPath(jsFnFullName);
|
||||
const jsAction: ReturnType<typeof getJSActionFromName> = yield select(
|
||||
(state: AppState) =>
|
||||
getJSActionFromName(state, JSObjectName, functionName),
|
||||
);
|
||||
const triggeredWidget: ReturnType<typeof getWidget> | undefined =
|
||||
yield select((state: AppState) =>
|
||||
getWidget(state, triggerMeta.source?.id || ""),
|
||||
);
|
||||
const dynamicPropertyPathList = triggeredWidget?.dynamicPropertyPathList;
|
||||
const isJSToggled = !!dynamicPropertyPathList?.find(
|
||||
(property) => property.key === triggerMeta.triggerPropertyName,
|
||||
);
|
||||
AnalyticsUtil.logEvent("EXECUTE_ACTION", {
|
||||
type: "JS",
|
||||
name: functionName,
|
||||
JSObjectName,
|
||||
pageId,
|
||||
appId,
|
||||
appMode,
|
||||
appName,
|
||||
isExampleApp,
|
||||
actionId: jsAction?.id,
|
||||
userData: {
|
||||
userId,
|
||||
email,
|
||||
appId,
|
||||
source,
|
||||
},
|
||||
widgetName: triggeredWidget?.widgetName,
|
||||
widgetType: triggeredWidget?.type,
|
||||
propertyName: triggerMeta.triggerPropertyName,
|
||||
isJSToggled,
|
||||
instanceId,
|
||||
});
|
||||
|
||||
AnalyticsUtil.logEvent(
|
||||
isSuccess ? "EXECUTE_ACTION_SUCCESS" : "EXECUTE_ACTION_FAILURE",
|
||||
{
|
||||
type: "JS",
|
||||
name: functionName,
|
||||
JSObjectName,
|
||||
pageId,
|
||||
appId,
|
||||
appMode,
|
||||
appName,
|
||||
isExampleApp,
|
||||
actionId: jsAction?.id,
|
||||
userData: {
|
||||
userId,
|
||||
email,
|
||||
appId,
|
||||
source,
|
||||
},
|
||||
widgetName: triggeredWidget?.widgetName,
|
||||
widgetType: triggeredWidget?.type,
|
||||
propertyName: triggerMeta.triggerPropertyName,
|
||||
isJSToggled,
|
||||
instanceId,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,4 +1,16 @@
|
|||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
export function postJSFunctionExecutionLog(fullName: string) {
|
||||
//
|
||||
import TriggerEmitter, {
|
||||
BatchKey,
|
||||
} from "workers/Evaluation/fns/utils/TriggerEmitter";
|
||||
import type { PostProcessorArg } from "workers/Evaluation/fns/utils/jsObjectFnFactory";
|
||||
|
||||
export function postJSFunctionExecutionLog({
|
||||
executionMetaData,
|
||||
isSuccess,
|
||||
jsFnFullName,
|
||||
}: PostProcessorArg) {
|
||||
TriggerEmitter.emit(BatchKey.process_batched_fn_invoke_log, {
|
||||
jsFnFullName,
|
||||
isSuccess,
|
||||
triggerMeta: executionMetaData.triggerMeta,
|
||||
});
|
||||
}
|
||||
|
|
|
|||
1
app/client/src/ee/sagas/analyticsSaga.ts
Normal file
1
app/client/src/ee/sagas/analyticsSaga.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export * from "../../ce/sagas/analyticsSaga";
|
||||
|
|
@ -30,7 +30,6 @@ import isEmpty from "lodash/isEmpty";
|
|||
import type { UnEvalTree } from "entities/DataTree/dataTreeFactory";
|
||||
import { sortJSExecutionDataByCollectionId } from "workers/Evaluation/JSObject/utils";
|
||||
import type { LintTreeSagaRequestData } from "plugins/Linting/types";
|
||||
import AnalyticsUtil from "utils/AnalyticsUtil";
|
||||
export type UpdateDataTreeMessageData = {
|
||||
workerResponse: EvalTreeResponseData;
|
||||
unevalTree: UnEvalTree;
|
||||
|
|
@ -106,19 +105,6 @@ export function* processTriggerHandler(message: any) {
|
|||
if (messageType === MessageType.REQUEST)
|
||||
yield call(evalWorker.respond, message.messageId, result);
|
||||
}
|
||||
export function* handleJSExecutionLog(data: TMessage<{ data: string[] }>) {
|
||||
const {
|
||||
body: { data: executedFns },
|
||||
} = data;
|
||||
|
||||
for (const executedFn of executedFns) {
|
||||
AnalyticsUtil.logEvent("EXECUTE_ACTION", {
|
||||
type: "JS",
|
||||
name: executedFn,
|
||||
});
|
||||
}
|
||||
yield call(logJSFunctionExecution, data);
|
||||
}
|
||||
|
||||
export function* handleEvalWorkerMessage(message: TMessage<any>) {
|
||||
const { body } = message;
|
||||
|
|
@ -145,7 +131,7 @@ export function* handleEvalWorkerMessage(message: TMessage<any>) {
|
|||
break;
|
||||
}
|
||||
case MAIN_THREAD_ACTION.LOG_JS_FUNCTION_EXECUTION: {
|
||||
yield call(handleJSExecutionLog, message);
|
||||
yield call(logJSFunctionExecution, message);
|
||||
break;
|
||||
}
|
||||
case MAIN_THREAD_ACTION.PROCESS_BATCHED_TRIGGERS: {
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ import { getAppsmithConfigs } from "@appsmith/configs";
|
|||
import { executeJSUpdates } from "actions/pluginActionActions";
|
||||
import { setEvaluatedActionSelectorField } from "actions/actionSelectorActions";
|
||||
import { waitForWidgetConfigBuild } from "./InitSagas";
|
||||
import { logDynamicTriggerExecution } from "@appsmith/sagas/analyticsSaga";
|
||||
|
||||
const APPSMITH_CONFIGS = getAppsmithConfigs();
|
||||
|
||||
|
|
@ -315,7 +316,6 @@ export function* evaluateAndExecuteDynamicTrigger(
|
|||
const unEvalTree: ReturnType<typeof getUnevaluatedDataTree> = yield select(
|
||||
getUnevaluatedDataTree,
|
||||
);
|
||||
// const unEvalTree = unEvalAndConfigTree.unEvalTree;
|
||||
log.debug({ execute: dynamicTrigger });
|
||||
const response: { errors: EvaluationError[]; result: unknown } = yield call(
|
||||
evalWorker.request,
|
||||
|
|
@ -331,6 +331,11 @@ export function* evaluateAndExecuteDynamicTrigger(
|
|||
);
|
||||
const { errors = [] } = response as any;
|
||||
yield call(dynamicTriggerErrorHandler, errors);
|
||||
yield fork(logDynamicTriggerExecution, {
|
||||
dynamicTrigger,
|
||||
errors,
|
||||
triggerMeta,
|
||||
});
|
||||
return response;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -515,6 +515,24 @@ export const getJSCollectionFromName = createSelector(
|
|||
return currentJSCollection;
|
||||
},
|
||||
);
|
||||
export const getJSActionFromName = createSelector(
|
||||
[
|
||||
(state: AppState, jsCollectionName: string) =>
|
||||
getJSCollectionFromName(state, jsCollectionName),
|
||||
(_state: AppState, jsCollectionName: string, functionName: string) => ({
|
||||
jsCollectionName,
|
||||
functionName,
|
||||
}),
|
||||
],
|
||||
(JSCollectionData, { functionName }) => {
|
||||
if (!JSCollectionData) return null;
|
||||
const jsFunction = find(
|
||||
JSCollectionData.config.actions,
|
||||
(action) => action.name === functionName,
|
||||
);
|
||||
return jsFunction || null;
|
||||
},
|
||||
);
|
||||
|
||||
export const getJSActionFromJSCollection = (
|
||||
JSCollection: JSCollectionData,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import type {
|
||||
ConfigTree,
|
||||
DataTree,
|
||||
AppsmithEntity,
|
||||
DataTreeEntity,
|
||||
} from "entities/DataTree/dataTreeFactory";
|
||||
import { EvaluationSubstitutionType } from "entities/DataTree/dataTreeFactory";
|
||||
|
|
@ -22,7 +21,6 @@ import {
|
|||
isJSAction,
|
||||
} from "@appsmith/workers/Evaluation/evaluationUtils";
|
||||
import JSObjectCollection from "./Collection";
|
||||
import type { APP_MODE } from "entities/App";
|
||||
import type {
|
||||
JSActionEntityConfig,
|
||||
JSActionEntity,
|
||||
|
|
@ -272,11 +270,6 @@ export function isJSObjectVariable(
|
|||
);
|
||||
}
|
||||
|
||||
export function getAppMode(dataTree: DataTree) {
|
||||
const appsmithObj = dataTree.appsmith as AppsmithEntity;
|
||||
return appsmithObj.mode as APP_MODE;
|
||||
}
|
||||
|
||||
export function isPromise(value: any): value is Promise<unknown> {
|
||||
return Boolean(value && typeof value.then === "function");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,10 @@ import { get } from "lodash";
|
|||
import { getType } from "utils/TypeHelpers";
|
||||
import type { JSVarMutatedEvents } from "workers/Evaluation/types";
|
||||
import { dataTreeEvaluator } from "workers/Evaluation/handlers/evalTree";
|
||||
import type {
|
||||
TriggerKind,
|
||||
TriggerSource,
|
||||
} from "constants/AppsmithActionConstants/ActionConstants";
|
||||
|
||||
const _internalSetTimeout = self.setTimeout;
|
||||
const _internalClearTimeout = self.clearTimeout;
|
||||
|
|
@ -182,15 +186,20 @@ TriggerEmitter.on(
|
|||
jsVariableUpdatesHandlerWrapper,
|
||||
);
|
||||
|
||||
export const fnInvokeLogHandler = priorityBatchedActionHandler<string>(
|
||||
(data) => {
|
||||
const set = new Set([...data]);
|
||||
WorkerMessenger.ping({
|
||||
method: MAIN_THREAD_ACTION.LOG_JS_FUNCTION_EXECUTION,
|
||||
data: [...set],
|
||||
});
|
||||
},
|
||||
);
|
||||
export const fnInvokeLogHandler = deferredBatchedActionHandler<{
|
||||
jsFnFullName: string;
|
||||
isSuccess: boolean;
|
||||
triggerMeta: {
|
||||
source: TriggerSource;
|
||||
triggerPropertyName: string | undefined;
|
||||
triggerKind: TriggerKind | undefined;
|
||||
};
|
||||
}>((data) => {
|
||||
WorkerMessenger.ping({
|
||||
method: MAIN_THREAD_ACTION.LOG_JS_FUNCTION_EXECUTION,
|
||||
data,
|
||||
});
|
||||
});
|
||||
|
||||
TriggerEmitter.on(BatchKey.process_batched_fn_invoke_log, fnInvokeLogHandler);
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ import { isPromise } from "workers/Evaluation/JSObject/utils";
|
|||
import { postJSFunctionExecutionLog } from "@appsmith/workers/Evaluation/JSObject/postJSFunctionExecution";
|
||||
import TriggerEmitter, { BatchKey } from "./TriggerEmitter";
|
||||
import ExecutionMetaData from "./ExecutionMetaData";
|
||||
import { TriggerKind } from "constants/AppsmithActionConstants/ActionConstants";
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
|
|
@ -16,6 +15,7 @@ export type PostProcessorArg = {
|
|||
executionMetaData: ReturnType<typeof ExecutionMetaData.getExecutionMetaData>;
|
||||
jsFnFullName: string;
|
||||
executionResponse: unknown;
|
||||
isSuccess: boolean;
|
||||
};
|
||||
|
||||
export type PostProcessor = (args: PostProcessorArg) => void;
|
||||
|
|
@ -34,23 +34,13 @@ function saveExecutionData({
|
|||
});
|
||||
}
|
||||
|
||||
function logJSExecution({ executionMetaData, jsFnFullName }: PostProcessorArg) {
|
||||
switch (executionMetaData.triggerMeta.triggerKind) {
|
||||
case TriggerKind.EVENT_EXECUTION: {
|
||||
TriggerEmitter.emit(BatchKey.process_batched_fn_invoke_log, jsFnFullName);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
postJSFunctionExecutionLog(jsFnFullName);
|
||||
}
|
||||
|
||||
export function jsObjectFunctionFactory<P extends ReadonlyArray<unknown>>(
|
||||
fn: (...args: P) => unknown,
|
||||
name: string,
|
||||
postProcessors: PostProcessor[] = [saveExecutionData, logJSExecution],
|
||||
postProcessors: PostProcessor[] = [
|
||||
saveExecutionData,
|
||||
postJSFunctionExecutionLog,
|
||||
],
|
||||
) {
|
||||
return function (this: unknown, ...args: P) {
|
||||
if (!ExecutionMetaData.getExecutionMetaData().enableJSFnPostProcessors) {
|
||||
|
|
@ -66,6 +56,7 @@ export function jsObjectFunctionFactory<P extends ReadonlyArray<unknown>>(
|
|||
executionMetaData,
|
||||
jsFnFullName: name,
|
||||
executionResponse: res,
|
||||
isSuccess: true,
|
||||
}),
|
||||
);
|
||||
return res;
|
||||
|
|
@ -76,6 +67,7 @@ export function jsObjectFunctionFactory<P extends ReadonlyArray<unknown>>(
|
|||
executionMetaData,
|
||||
jsFnFullName: name,
|
||||
executionResponse: undefined,
|
||||
isSuccess: true,
|
||||
}),
|
||||
);
|
||||
throw e;
|
||||
|
|
@ -86,6 +78,7 @@ export function jsObjectFunctionFactory<P extends ReadonlyArray<unknown>>(
|
|||
executionMetaData,
|
||||
jsFnFullName: name,
|
||||
executionResponse: result,
|
||||
isSuccess: true,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
|
@ -96,6 +89,7 @@ export function jsObjectFunctionFactory<P extends ReadonlyArray<unknown>>(
|
|||
executionMetaData,
|
||||
jsFnFullName: name,
|
||||
executionResponse: undefined,
|
||||
isSuccess: false,
|
||||
});
|
||||
});
|
||||
throw e;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user