Analytics for debugger errors (#5660)

This commit is contained in:
akash-codemonk 2021-07-08 11:01:08 +05:30 committed by Rishabh Saxena
parent 0f32cf10b6
commit 45276c9e56
5 changed files with 139 additions and 6 deletions

View File

@ -1,5 +1,15 @@
import { ReduxActionTypes } from "constants/ReduxActionConstants";
import { Message } from "entities/AppsmithConsole";
import { Message, ENTITY_TYPE } from "entities/AppsmithConsole";
import { EventName } from "utils/AnalyticsUtil";
export interface LogDebuggerErrorAnalyticsPayload {
entityName: string;
entityId: string;
entityType: ENTITY_TYPE;
eventName: EventName;
propertyPath: string;
errorMessages: { message: string }[];
}
export const debuggerLogInit = (payload: Message) => ({
type: ReduxActionTypes.DEBUGGER_LOG_INIT,
@ -29,3 +39,11 @@ export const updateErrorLog = (payload: Message) => ({
type: ReduxActionTypes.DEBUGGER_UPDATE_ERROR_LOG,
payload,
});
// Only used for analytics
export const logDebuggerErrorAnalytics = (
payload: LogDebuggerErrorAnalyticsPayload,
) => ({
type: ReduxActionTypes.DEBUGGER_ERROR_ANALYTICS,
payload,
});

View File

@ -118,6 +118,7 @@ export const ReduxActionTypes: { [key: string]: string } = {
DEBUGGER_ERROR_LOG: "DEBUGGER_ERROR_LOG",
DEBUGGER_UPDATE_ERROR_LOG: "DEBUGGER_UPDATE_ERROR_LOG",
DEBUGGER_UPDATE_ERROR_LOGS: "DEBUGGER_UPDATE_ERROR_LOGS",
DEBUGGER_ERROR_ANALYTICS: "DEBUGGER_ERROR_ANALYTICS",
CLEAR_DEBUGGER_LOGS: "CLEAR_DEBUGGER_LOGS",
SHOW_DEBUGGER: "SHOW_DEBUGGER",
SET_THEME: "SET_THEME",

View File

@ -1,4 +1,10 @@
import { debuggerLog, errorLog, updateErrorLog } from "actions/debuggerActions";
import {
debuggerLog,
errorLog,
logDebuggerErrorAnalytics,
LogDebuggerErrorAnalyticsPayload,
updateErrorLog,
} from "actions/debuggerActions";
import { ReduxAction, ReduxActionTypes } from "constants/ReduxActionConstants";
import {
ENTITY_TYPE,
@ -16,7 +22,7 @@ import {
} from "redux-saga/effects";
import { get, set } from "lodash";
import { getDebuggerErrors } from "selectors/debuggerSelectors";
import { getAction } from "selectors/entitiesSelector";
import { getAction, getPlugin } from "selectors/entitiesSelector";
import { Action, PluginType } from "entities/Action";
import LOG_TYPE from "entities/AppsmithConsole/logtype";
import { DataTree } from "entities/DataTree/dataTreeFactory";
@ -35,6 +41,11 @@ import {
createMessage,
WIDGET_PROPERTIES_UPDATED,
} from "constants/messages";
import AnalyticsUtil from "utils/AnalyticsUtil";
import { Plugin } from "api/PluginApi";
import { getCurrentPageId } from "selectors/editorSelectors";
import { getWidget } from "./selectors";
import { WidgetProps } from "widgets/BaseWidget";
function* formatActionRequestSaga(payload: LogActionPayload, request?: any) {
if (!payload.source || !payload.state || !request || !request.headers) {
@ -141,6 +152,9 @@ function* logDependentEntityProperties(payload: Message) {
function* debuggerLogSaga(action: ReduxAction<Message>) {
const { payload } = action;
const debuggerErrors: Record<string, Message> = yield select(
getDebuggerErrors,
);
switch (payload.logType) {
case LOG_TYPE.WIDGET_UPDATE:
@ -166,6 +180,19 @@ function* debuggerLogSaga(action: ReduxAction<Message>) {
const res = yield call(formatActionRequestSaga, payload, payload.state);
const log = { ...payload };
res && set(log, "state.headers", res);
if (!((payload.source?.id as string) in debuggerErrors)) {
yield put(
logDebuggerErrorAnalytics({
eventName: "DEBUGGER_NEW_ERROR",
errorMessages: payload.messages ?? [],
entityType: ENTITY_TYPE.ACTION,
entityId: payload.source?.id ?? "",
entityName: payload.source?.name ?? "",
propertyPath: "",
}),
);
}
yield put(errorLog(log));
yield put(debuggerLog(log));
}
@ -178,6 +205,19 @@ function* debuggerLogSaga(action: ReduxAction<Message>) {
payload.state?.request ?? {},
);
if ((payload.source?.id as string) in debuggerErrors) {
yield put(
logDebuggerErrorAnalytics({
eventName: "DEBUGGER_RESOLVED_ERROR",
errorMessages:
debuggerErrors[payload.source?.id ?? ""].messages ?? [],
entityType: ENTITY_TYPE.ACTION,
entityId: payload.source?.id ?? "",
entityName: payload.source?.name ?? "",
propertyPath: "",
}),
);
}
yield put(
updateErrorLog({
...payload,
@ -198,6 +238,51 @@ function* debuggerLogSaga(action: ReduxAction<Message>) {
}
}
export default function* debuggerSagasListeners() {
yield all([takeEvery(ReduxActionTypes.DEBUGGER_LOG_INIT, debuggerLogSaga)]);
// This saga is intended for analytics only
function* logDebuggerErrorAnalyticsSaga(
action: ReduxAction<LogDebuggerErrorAnalyticsPayload>,
) {
const { payload } = action;
const currentPageId = yield select(getCurrentPageId);
if (payload.entityType === ENTITY_TYPE.WIDGET) {
const widget: WidgetProps = yield select(getWidget, payload.entityId);
const widgetType = widget.type;
const propertyPath = `${widgetType}.${payload.propertyPath}`;
// Sending widget type for widgets
AnalyticsUtil.logEvent(payload.eventName, {
entityType: widgetType,
propertyPath,
errorMessages: payload.errorMessages,
pageId: currentPageId,
});
} else if (payload.entityType === ENTITY_TYPE.ACTION) {
const action: Action = yield select(getAction, payload.entityId);
const plugin: Plugin = yield select(getPlugin, action.pluginId);
const pluginName = plugin.name.replace(/ /g, "");
let propertyPath = `${pluginName}`;
if (payload.propertyPath) {
propertyPath += `.${payload.propertyPath}`;
}
// Sending plugin name for actions
AnalyticsUtil.logEvent(payload.eventName, {
entityType: pluginName,
propertyPath,
errorMessages: payload.errorMessages,
pageId: currentPageId,
});
}
}
export default function* debuggerSagasListeners() {
yield all([
takeEvery(ReduxActionTypes.DEBUGGER_LOG_INIT, debuggerLogSaga),
takeEvery(
ReduxActionTypes.DEBUGGER_ERROR_ANALYTICS,
logDebuggerErrorAnalyticsSaga,
),
]);
}

View File

@ -57,6 +57,8 @@ import {
} from "constants/messages";
import { getAppMode } from "selectors/applicationSelectors";
import { APP_MODE } from "reducers/entityReducers/appReducer";
import store from "store";
import { logDebuggerErrorAnalytics } from "actions/debuggerActions";
let widgetTypeConfigMap: WidgetTypeConfigMap;
@ -112,6 +114,19 @@ function getLatestEvalPropertyErrors(
message: e.errorMessage,
}));
if (!(debuggerKey in updatedDebuggerErrors)) {
store.dispatch(
logDebuggerErrorAnalytics({
eventName: "DEBUGGER_NEW_ERROR",
entityId: idField,
entityName: nameField,
entityType,
propertyPath,
errorMessages,
}),
);
}
// Add or update
updatedDebuggerErrors[debuggerKey] = {
logType: LOG_TYPE.EVAL_ERROR,
@ -132,6 +147,17 @@ function getLatestEvalPropertyErrors(
},
};
} else if (debuggerKey in updatedDebuggerErrors) {
store.dispatch(
logDebuggerErrorAnalytics({
eventName: "DEBUGGER_RESOLVED_ERROR",
entityId: idField,
entityName: nameField,
entityType,
propertyPath:
updatedDebuggerErrors[debuggerKey].source?.propertyPath ?? "",
errorMessages: updatedDebuggerErrors[debuggerKey].messages ?? [],
}),
);
// Remove
delete updatedDebuggerErrors[debuggerKey];
}

View File

@ -124,7 +124,10 @@ export type EventName =
| "GSHEET_AUTH_COMPLETE"
| "CYCLICAL_DEPENDENCY_ERROR"
| "DISCORD_LINK_CLICK"
| "BINDING_SUCCESS";
| "BINDING_SUCCESS"
| "SLASH_COMMAND"
| "DEBUGGER_NEW_ERROR"
| "DEBUGGER_RESOLVED_ERROR";
function getApplicationId(location: Location) {
const pathSplit = location.pathname.split("/");