mirror of
				https://github.com/Tencent/tmagic-editor.git
				synced 2025-11-04 18:52:18 +08:00 
			
		
		
		
	feat(core): 添加error hander配置
This commit is contained in:
		
							parent
							
								
									378c75658d
								
							
						
					
					
						commit
						6dc007388b
					
				@ -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();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -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') {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user