import { NFError } from "../error"; import { NFNodeType } from "../types"; import { NFNode } from "./node"; /** * 可执行模块节点。 * * 模块需导出 `function(process){ ... }`,可将结果写入流程变量。 * * @example * module.exports = function(process){ * process.setParam('result', 1); * } */ export class NFModuleNode extends NFNode{ /** * 模块路径 */ modulePath:string; /** * 创建模块节点。 * * @param cfg - 需含 `path` * @param process - 所属流程 * @throws `1101` 当缺少 `path` */ constructor(cfg,process){ super(cfg,process); this.type = NFNodeType.MODULETASK; if(!cfg.path){ throw new NFError("1101",[cfg.name || cfg.id || 'moduletask']); } this.modulePath = require('path').resolve(cfg.path); } /** * 加载并执行模块函数,成功后沿出口继续。 * * @throws `1102` 当模块无法加载、导出非函数或执行失败 */ async run() { await super.run(); let fn:any; try{ const mod = await import(this.modulePath); fn = typeof mod === 'function' ? mod : (mod.default ?? mod); }catch(e){ throw new NFError("1102",[this.name || this.id, this.stringifyError(e)]); } if(typeof fn !== 'function'){ throw new NFError("1102",[this.name || this.id, 'module export is not a function']); } try{ await fn(this.process); }catch(e){ // 模块执行失败:中断流转,不进入后续节点 throw new NFError("1102",[this.name || this.id, this.stringifyError(e)]); } const seq = this.process.nodeManager.getSequenceNode(this.id); if(seq){ await seq.run(); } } /** * 将异常转为可读字符串。 * * @param e - 捕获的错误 * @returns 错误描述 */ private stringifyError(e:any):string{ if(!e){ return 'unknown error'; } if(typeof e === 'string'){ return e; } return e.message || String(e); } }