快速定位
下面列出各阶段的典型错误与立即检查项:- 解析:
MultipleParseException- 立即检查:
ex.formatDiagnostic()打印源码摘录 - REPL:语句前加
$输出 AST
- 立即检查:
- 分派:
FunctionNotFoundError/EvaluatorNotFoundError- 立即检查:
Environment#getRootFunctions()/getRootExtensionFunctions() - 命名空间与 target 类型是否匹配
- 立即检查:
- 数据:
ArgumentTypeMismatchError/VariableNotFoundError/IndexAccessError/VoidError- 立即检查:
FunctionContext#toString()(函数名/target/参数) - 参考:
availableVariables、IndexErrorType
- 立即检查:
- 并发:主线程函数跑在后台 / 异步任务堆积
- 立即检查:
registerPrimarySyncFunction用法 - 观察:
ThreadPoolManager#getActiveTaskCount()与执行器配置
- 立即检查:
解析错误(MultipleParseException)
Parser#parse聚合所有语法错误;ex.formatDiagnostic()可直接打印行列与源码摘录。- REPL 语句前加
$,控制台会输出词法/语法树,便于确认括号、then/else是否成对。 - 网络/数据库来源的脚本注意行尾统一,否则列号可能偏移。
调用分派问题
FunctionNotFoundError
- 注册是否生效:
Environment#getRootFunctions()/getRootExtensionFunctions()查看。 缺失则重新注册并调用runtime.newEnvironment()触发 bake。 - 命名空间:
registerFunction("fs", "readText", …)对应脚本fs:readText,漏前缀会直接失败。 - target 类型:扩展函数要求
target与注册类型一致;null::fn()会因 target 为空而匹配不到。 - 目录一致性:必要时重跑
./gradlew :core:dumpFluxonCatalog,确认导出的签名与预期一致。
EvaluatorNotFoundError
- 新增语法未提供求值器导致。
- 检查是否在
runtime.function/index注册 evaluator。 - 如果语法应被禁止,在解析阶段直接抛
ParseException,避免运行时才失败。
数据与类型问题
ArgumentTypeMismatchError
FunctionContext#getInt/getAsDouble等方法会在消息中标注参数索引与实际值;先核实脚本入参是否符合签名。- 多参数版本只检查参数个数,不会自动装箱;需要在实现内区分
Number/String等类型。 - 扩展函数建议先用
getArgumentCount()判断参数个数,避免索引越界。
VariableNotFoundError
:vars(REPL)或Environment#getRootVariables()查看当前可见变量;确认作用域与命名是否一致。- 函数体中新增局部变量时,确保解析器同步更新
localVariableNames,否则赋值索引会错位。
IndexAccessError
OUT_OF_BOUNDS:检查索引与集合大小。UNSUPPORTED_TYPE/UNSUPPORTED_SET_TYPE:该类型未实现IndexAccessor,需要添加实现或更换访问方式。NULL_TARGET:目标为null;脚本侧加判空或默认值(Elvis)再访问。
VoidError
函数返回Function.VOID 却继续参与运算时触发。仅在确实无需返回值的路径返回 VOID,其他场景返回真实结果或 null。
并发与执行器
- 主线程函数:仅通过
registerPrimarySyncFunction/registerSyncExtensionFunction标记。 - 执行器:使用
FluxonRuntime#setPrimaryThreadExecutor指向宿主主线程。 - 异步任务:
ThreadPoolManager#getActiveTaskCount()观察堆积。 - 若出现
CallerRunsPolicy,表示队列满,新任务会落到调用线程;需要拆批或扩容。 - 关闭:
ThreadPoolManager#shutdown()前最好等待awaitTermination,避免异步任务被硬中断。
现场信息速查
Environment#getRootFunctions()/getRootExtensionFunctions()/getRootVariables():注册表与可见符号。FunctionContext#toString():函数名、target、参数实参。FluxonRuntime#getSystemFunctions()/#getExtensionFunctions():宿主侧直接查看注册状态。./gradlew :core:dumpFluxonCatalog+vscode-extension/scripts/sync-catalog.js:当补全或文档与运行时不一致时优先刷新。