升级Jint至3.0.1后触发空引用异常,求排查解决方法
Jint 3.0.1升级后脚本执行抛出NullReferenceException问题
问题概述
原本在Jint 3.0.0-beta-2033中正常运行的脚本,升级至3.0.1及最新正式版后执行时抛出Object reference not set to an instance of an object异常,已尝试替换脚本空值但无效。
涉事脚本代码
(function () { var callResult; var flowHelper = require('flowHelper'); var serverScriptExecutionContext = flowHelper.getServerScriptExecutionContext(context,request,args,readConfig,result,log,flowHelper); var Fields = args.Fields; var fieldsDataForSave = flowHelper.getValidatedPageDataForLoanCalculation(serverScriptExecutionContext); log.LogDebug('Calculate Loan Conditions Action fieldsDataForSave: ' + JSON.stringify(fieldsDataForSave)); callResult = JSON.parse(__remote_call__(context.nodes.loans, 'SaveFields', __jsonify__({"appId": context.AppId, "fields": fieldsDataForSave}))); }());
完整错误日志
Method CalculateLoanConditions has thrown an exception. System.NullReferenceException: Object reference not set to an instance of an object. at Jint.Runtime.Interpreter.Expressions.JintExpression.GetValue(EvaluationContext context) at Jint.EsprimaExtensions.TryGetKey[T](T expression, Engine engine, Boolean resolveComputed) at Jint.Runtime.Interpreter.Expressions.JintObjectExpression.BuildObjectNormal(EvaluationContext context) at Jint.Runtime.Interpreter.Expressions.JintExpression.GetValue(EvaluationContext context) at Jint.Runtime.Interpreter.Expressions.JintCallExpression.ArgumentListEvaluation(EvaluationContext context) at Jint.Runtime.Interpreter.Expressions.JintCallExpression.EvaluateInternal(EvaluationContext context) at Jint.Runtime.Interpreter.Expressions.JintExpression.GetValue(EvaluationContext context) at Jint.Runtime.Interpreter.Statements.JintReturnStatement.ExecuteInternal(EvaluationContext context) at Jint.Native.Function.ScriptFunction.Call(JsValue thisObject, JsValue[] arguments) at Jint.Runtime.Interpreter.Expressions.JintCallExpression.EvaluateInternal(EvaluationContext context) at Jint.Runtime.Interpreter.Expressions.JintExpression.GetValue(EvaluationContext context) at Jint.Runtime.Interpreter.Statements.JintReturnStatement.ExecuteInternal(EvaluationContext context) at Jint.Native.Function.ScriptFunction.Call(JsValue thisObject, JsValue[] arguments) at Jint.Runtime.Interpreter.Expressions.JintCallExpression.EvaluateInternal(EvaluationContext context) at Jint.Runtime.Interpreter.Expressions.JintExpression.GetValue(EvaluationContext context) at Jint.Runtime.Interpreter.Statements.JintVariableDeclaration.ExecuteInternal(EvaluationContext context) at Jint.Native.Function.ScriptFunction.Call(JsValue thisObject, JsValue[] arguments) at Jint.Runtime.Interpreter.Expressions.JintCallExpression.EvaluateInternal(EvaluationContext context) at Jint.Runtime.Interpreter.Expressions.JintExpression.GetValue(EvaluationContext context) at Jint.Runtime.Interpreter.Statements.JintVariableDeclaration.ExecuteInternal(EvaluationContext context) at Jint.Native.Function.ScriptFunction.Call(JsValue thisObject, JsValue[] arguments) at Jint.Runtime.Interpreter.Expressions.JintCallExpression.EvaluateInternal(EvaluationContext context) at Jint.Runtime.Interpreter.Expressions.JintExpression.GetValue(EvaluationContext context) at Jint.Runtime.Interpreter.Expressions.JintAssignmentExpression.SimpleAssignmentExpression.AssignToIdentifier(EvaluationContext context, JintIdentifierExpression left, JintExpression right, Boolean hasEvalOrArguments) at Jint.Runtime.Interpreter.Statements.JintVariableDeclaration.ExecuteInternal(EvaluationContext context) at Jint.Native.Function.ScriptFunction.Call(JsValue thisObject, JsValue[] arguments) at Jint.Runtime.Interpreter.Expressions.JintCallExpression.EvaluateInternal(EvaluationContext context) at Jint.Runtime.Interpreter.Expressions.JintExpression.GetValue(EvaluationContext context) at Jint.Runtime.Interpreter.Statements.JintExpressionStatement.ExecuteInternal(EvaluationContext context) at Jint.Engine.ScriptEvaluation(ScriptRecord scriptRecord) at Jint.Engine.ExecuteWithConstraints[T](Boolean strict, Func`1 callback) at Jint.Engine.Execute(Script script) at Jint.Engine.Evaluate(String code) at Lending.FrozenFlow.Core.DSL.Misc.ScriptFlow.ExecuteScriptOptimisticallyAndGetNextPage(ExecutionContext`1 result, String script) in C:\ML\as.accessdigital.lending.shared.babbler.nodes\AS.Lending.FrozenFlow.Core\DSL\Misc\ScriptFlow.cs:line 173 at Lending.FrozenFlow.Core.DSL.Misc.ScriptFlow.<>c__DisplayClass19_0.b__0(ExecutionContext`1 result) in C:\ML\as.accessdigital.lending.shared.babbler.nodes\AS.Lending.FrozenFlow.Core\DSL\Misc\ScriptFlow.cs:line 201
根本原因分析
从错误栈来看,异常发生在JintObjectExpression.BuildObjectNormal方法中,说明Jint在解析脚本中的对象字面量{"appId": context.AppId, "fields": fieldsDataForSave}时出现空引用。结合版本差异,大概率是Jint 3.0.1之后对对象字面量中null值的处理逻辑发生了变化,或者自定义的__jsonify__函数在新版本Jint下无法正确处理null类型的JsValue,导致.NET端出现空引用。
解决方法
提前检查关键变量是否为null
在调用__jsonify__前添加变量校验,避免传入null值触发异常:// 校验关键变量 if (context.AppId === null || context.AppId === undefined) { log.LogError('context.AppId is missing or null'); return; } if (fieldsDataForSave === null || fieldsDataForSave === undefined) { log.LogError('fieldsDataForSave is missing or null'); return; } // 执行远程调用 callResult = JSON.parse(__remote_call__(context.nodes.loans, 'SaveFields', __jsonify__({"appId": context.AppId, "fields": fieldsDataForSave})));分步构建对象替代字面量
绕过Jint对对象字面量的直接解析,改用分步赋值的方式创建参数对象:var params = {}; params.appId = context.AppId ?? null; params.fields = fieldsDataForSave ?? null; callResult = JSON.parse(__remote_call__(context.nodes.loans, 'SaveFields', __jsonify__(params)));排查自定义
__jsonify__函数的兼容性
如果__jsonify__是你方实现的.NET扩展函数,检查其处理JsValue的逻辑:- 确保在处理JsValue为
JsNull或JsUndefined时不会直接调用null对象的方法 - 适配Jint 3.0.1及以上版本中JsValue的类型判断逻辑(比如新版本中
IsNull和IsUndefined的判断方式是否有变化)
- 确保在处理JsValue为
检查Jint引擎配置
确认升级后是否开启了严格模式或其他行为变更的配置,若有尝试关闭:var engine = new Engine(options => { // 若开启了严格模式,尝试注释掉 // options.SetStrictMode(true); });
内容的提问来源于stack exchange,提问作者user24343590
相关产品推荐
相关产品推荐

