feat(core): 添加error hander配置

This commit is contained in:
roymondchen 2025-04-28 17:25:00 +08:00
parent 378c75658d
commit 6dc007388b
2 changed files with 71 additions and 19 deletions

View File

@ -20,8 +20,8 @@ import { EventEmitter } from 'events';
import { isEmpty } from 'lodash-es'; import { isEmpty } from 'lodash-es';
import { createDataSourceManager, DataSourceManager, ObservedDataClass } from '@tmagic/data-source'; import { createDataSourceManager, type DataSource, DataSourceManager, ObservedDataClass } from '@tmagic/data-source';
import type { CodeBlockDSL, Id, JsEngine, MApp, RequestFunction } from '@tmagic/schema'; import type { CodeBlockDSL, DataSourceSchema, Id, JsEngine, MApp, RequestFunction } from '@tmagic/schema';
import Env from './Env'; import Env from './Env';
import EventHelper from './EventHelper'; import EventHelper from './EventHelper';
@ -31,6 +31,12 @@ import Node from './Node';
import Page from './Page'; import Page from './Page';
import { transformStyle as defaultTransformStyle } from './utils'; import { transformStyle as defaultTransformStyle } from './utils';
export type ErrorHandler = (
err: Error,
node: DataSource<DataSourceSchema> | Node | undefined,
info: Record<string, any>,
) => void;
export interface AppOptionsConfig { export interface AppOptionsConfig {
ua?: string; ua?: string;
env?: Env; env?: Env;
@ -46,6 +52,7 @@ export interface AppOptionsConfig {
transformStyle?: (style: Record<string, any>) => Record<string, any>; transformStyle?: (style: Record<string, any>) => Record<string, any>;
request?: RequestFunction; request?: RequestFunction;
DataSourceObservedData?: ObservedDataClass; DataSourceObservedData?: ObservedDataClass;
errorHandler?: ErrorHandler;
} }
class App extends EventEmitter { class App extends EventEmitter {
@ -70,6 +77,7 @@ class App extends EventEmitter {
public request?: RequestFunction; public request?: RequestFunction;
public transformStyle: (style: Record<string, any>) => Record<string, any>; public transformStyle: (style: Record<string, any>) => Record<string, any>;
public eventHelper?: EventHelper; public eventHelper?: EventHelper;
public errorHandler?: ErrorHandler;
private flexible?: Flexible; private flexible?: Flexible;
@ -82,6 +90,8 @@ class App extends EventEmitter {
this.setEnv(options.ua); this.setEnv(options.ua);
} }
this.errorHandler = options.errorHandler;
// 代码块描述内容在dsl codeBlocks字段 // 代码块描述内容在dsl codeBlocks字段
this.codeDsl = options.config?.codeBlocks; this.codeDsl = options.config?.codeBlocks;
options.platform && (this.platform = options.platform); options.platform && (this.platform = options.platform);
@ -259,7 +269,15 @@ class App extends EventEmitter {
if (!codeId || isEmpty(this.codeDsl)) return; if (!codeId || isEmpty(this.codeDsl)) return;
const content = this.codeDsl?.[codeId]?.content; const content = this.codeDsl?.[codeId]?.content;
if (typeof content === 'function') { if (typeof content === 'function') {
await content({ app: this, params, eventParams: args, flowState }); try {
await content({ app: this, params, eventParams: args, flowState });
} catch (e: any) {
if (this.errorHandler) {
this.errorHandler(e, undefined, { type: 'run-code', codeId, params, eventParams: args, flowState });
} else {
throw e;
}
}
} }
} }
@ -283,7 +301,15 @@ class App extends EventEmitter {
if (!method) return; if (!method) return;
if (typeof method.content === 'function') { if (typeof method.content === 'function') {
await method.content({ app: this, params, dataSource, eventParams: args, flowState }); try {
await method.content({ app: this, params, dataSource, eventParams: args, flowState });
} catch (e: any) {
if (this.errorHandler) {
this.errorHandler(e, dataSource, { type: 'data-source-method', params, eventParams: args, flowState });
} else {
throw e;
}
}
} }
} }
@ -295,6 +321,13 @@ class App extends EventEmitter {
this.flexible = undefined; this.flexible = undefined;
this.eventHelper?.destroy(); this.eventHelper?.destroy();
this.dsl = undefined;
this.dataSourceManager?.destroy();
this.dataSourceManager = undefined;
this.codeDsl = undefined;
this.components.clear();
} }
} }

View File

@ -53,6 +53,8 @@ export default class EventHelper extends EventEmitter {
public destroy() { public destroy() {
this.removeNodeEvents(); this.removeNodeEvents();
this.removeAllListeners(); this.removeAllListeners();
this.nodeEventList.clear();
this.dataSourceEventList.clear();
} }
public bindNodeEvents(node: TMagicNode) { public bindNodeEvents(node: TMagicNode) {
@ -147,6 +149,7 @@ export default class EventHelper extends EventEmitter {
*/ */
private async eventHandler(config: EventConfig | number, fromCpt: TMagicNode | DataSource | undefined, args: any[]) { private async eventHandler(config: EventConfig | number, fromCpt: TMagicNode | DataSource | undefined, args: any[]) {
const eventConfig = typeof config === 'number' ? (fromCpt as TMagicNode).events[config] : config; const eventConfig = typeof config === 'number' ? (fromCpt as TMagicNode).events[config] : config;
if (has(eventConfig, 'actions')) { if (has(eventConfig, 'actions')) {
// EventConfig类型 // EventConfig类型
const flowState = new FlowState(); const flowState = new FlowState();
@ -163,8 +166,16 @@ export default class EventHelper extends EventEmitter {
} }
flowState.reset(); flowState.reset();
} else { } else {
// 兼容DeprecatedEventConfig类型 组件动作 try {
await this.compActionHandler(eventConfig as unknown as CompItemConfig, fromCpt as TMagicNode, args); // 兼容DeprecatedEventConfig类型 组件动作
await this.compActionHandler(eventConfig as unknown as CompItemConfig, fromCpt as TMagicNode, args);
} catch (e: any) {
if (this.app.errorHandler) {
this.app.errorHandler(e, fromCpt, { type: 'action-handler', config: eventConfig, ...args });
} else {
throw e;
}
}
} }
} }
@ -174,20 +185,28 @@ export default class EventHelper extends EventEmitter {
args: any[], args: any[],
flowState: FlowState, flowState: FlowState,
) { ) {
if (actionItem.actionType === ActionType.COMP) { try {
const compActionItem = actionItem as CompItemConfig; if (actionItem.actionType === ActionType.COMP) {
// 组件动作 const compActionItem = actionItem as CompItemConfig;
await this.compActionHandler(compActionItem, fromCpt, args); // 组件动作
} else if (actionItem.actionType === ActionType.CODE) { await this.compActionHandler(compActionItem, fromCpt, args);
const codeActionItem = actionItem as CodeItemConfig; } else if (actionItem.actionType === ActionType.CODE) {
// 执行代码块 const codeActionItem = actionItem as CodeItemConfig;
await this.app.runCode(codeActionItem.codeId, codeActionItem.params || {}, args, flowState); // 执行代码块
} else if (actionItem.actionType === ActionType.DATA_SOURCE) { await this.app.runCode(codeActionItem.codeId, codeActionItem.params || {}, args, flowState);
const dataSourceActionItem = actionItem as DataSourceItemConfig; } else if (actionItem.actionType === ActionType.DATA_SOURCE) {
const dataSourceActionItem = actionItem as DataSourceItemConfig;
const [dsId, methodName] = dataSourceActionItem.dataSourceMethod; const [dsId, methodName] = dataSourceActionItem.dataSourceMethod;
await this.app.runDataSourceMethod(dsId, methodName, dataSourceActionItem.params || {}, args, flowState); await this.app.runDataSourceMethod(dsId, methodName, dataSourceActionItem.params || {}, args, flowState);
}
} catch (e: any) {
if (this.app.errorHandler) {
this.app.errorHandler(e, fromCpt, { type: 'action-handler', config: actionItem, flowState, ...args });
} else {
throw e;
}
} }
} }
@ -206,7 +225,7 @@ export default class EventHelper extends EventEmitter {
} }
const toNode = this.app.getNode(to); const toNode = this.app.getNode(to);
if (!toNode) throw `ID为${to}的组件不存在`; if (!toNode) throw new Error(`ID为${to}的组件不存在`);
if (toNode.instance) { if (toNode.instance) {
if (typeof toNode.instance[methodName] === 'function') { if (typeof toNode.instance[methodName] === 'function') {