import type {NodeHandler, NodeResult} from '../../../types/bot/workflow/runtime.ts'; import type {WorkflowNodeTemplate} from '../../../types/bot/workflow/metadata.ts'; import {describe, failure_port, output, port} from '../metadata.ts'; export const config_template: WorkflowNodeTemplate = { name: 'error', version: '1.0.0', i18n: describe('异常分流', '检查上一节点的执行状态和错误代码,保留原执行结果并选择分支。'), config: [ {name: 'codes', type: 'array', required: false, i18n: describe('错误代码', '省略此字段时匹配全部失败结果;提供列表时仅匹配其中的错误代码,显式空列表不匹配任何错误。'), item: {name: 'code', type: 'string', required: true, i18n: describe('错误代码', '与上一节点 error.code 精确匹配的字符串。')}}, ], output: output('json', '上一节点输出', '透传上一节点的 output,缺失时为 null;失败分支保留原失败状态及可选错误。'), ports: [port('normal', '正常', '上一节点不存在或状态不是 failure 时执行,节点状态为 success。'), port('error', '匹配异常', '上一节点失败且匹配错误代码规则时执行,保留 failure 状态。'), port('unmatched', '未匹配异常', '上一节点失败但不匹配错误代码规则时执行,保留 failure 状态。'), failure_port], }; export const execute: NodeHandler = async (node, state, signal) => { if (node.type !== 'error') throw new Error('Expected an error node'); signal.throwIfAborted(); const previous = state.last_result; if (!previous || previous.status !== 'failure') { return {port: 'normal', result: {status: 'success', output: previous?.output ?? null}}; } const result: NodeResult = {status: previous.status, output: previous.output}; if (previous.error) result.error = {...previous.error}; const matches = node.config.codes === undefined || (previous.error !== undefined && node.config.codes.includes(previous.error.code)); return {port: matches ? 'error' : 'unmatched', result}; };