点击此处---> 群内免费提供SAP练习系统(在群公告中)加入QQ群:457200227(SAP S4 HANA技术交流) 群内免费提供SAP练习系统(在群公告中)尊敬的专家, 开...
点击此处---> 群内免费提供SAP练习系统(在群公告中)加入QQ群:457200227(SAP S4 HANA技术交流) 群内免费提供SAP练习系统(在群公告中)尊敬的专家, 开...
加入QQ群:457200227(SAP S4 HANA技术交流) 群内免费提供SAP练习系统(在群公告中)
尊敬的专家,
开发SE扩展程序我经常会遇到错误,我不太了解为什么。 我检查了所有本可以找到的文档,并花了大量时间进行谷歌搜索,但是对于我来说,有些要点仍然不清楚。 我准备了几个示例,因此,我希望社区(甚至SAP支持人员或解决方案架构师团队的人员)可以阐明这种行为的原因。 所有这些示例都在SAP B1 9.3 PL 03中进行了测试
示例1:
对我来说,这可能是最奇怪的问题。 在论坛和文档中的所有示例中,您都可以在脚本开头找到以下行:
var ServiceLayerContext = require('ServiceLayerContext.js');
只需要实例化此对象,它就可以正常工作。 以下内容也是如此:
var slContext = require('ServiceLayerContext.js');
但是,如果我将此变量称为" serviceLayerContext",则在实例化并调用方法" startTransaction()"后会收到奇怪的错误: 脚本错误:调用函数'POST'失败[TypeError:this.contextHandle .startTransaction不是函数]。
这是我的代码,其中会重现此错误:
var http = require('HttpModule.js'); //要求使用不同于ServiceLayerContext的名称 var serviceLayerContext = require('ServiceLayerContext.js'); 函数GET() { } 函数DELETE(){ } 函数PATCH(){ } 函数POST() { //实例化 var slObj = new serviceLayerContext(); //开始交易 slObj.startTransaction(); //立即回滚 如果(slObj.isInTransaction())slObj.rollbackTransaction(); /*设置HTTP响应*/ http.response.setContentType(http.ContentType.APPLICATION_JSON); http.response.setStatus(http.HttpStatus.HTTP_OK); http.response.setContent({status:'success'}); http.response.send(); }
如果我调用此脚本,则会得到以下响应正文:
{ "错误":{ "代码":512, "信息": { " lang":" zh-cn", "" value":"脚本错误:调用函数'POST'失败[TypeError:this.contextHandle.startTransaction不是函数]。" } } }
如果我将serviceLayerContext上下文重命名为ServiceLayerContext(例如slContext),一切都会顺利进行。
这是预期的行为还是我做错了什么?
示例2
在论坛和文档中的所有示例中,仅使用入口点功能。 在上传的JS文件中编写附加功能是否有限制? 原因如果我在方法函数之后编写函数,则会遇到意外行为(有时会导致错误,有时不会出错)。 通常是关于编译和意外令牌的错误(我得到了包括ILLEGAL在内的所有令牌的错误)
这是一个重现问题的代码示例:
var http = require('HttpModule.js'); 函数GET(){ } 函数PATCH(){ } 函数DELETE(){ } 函数POST(){ //测试要记录的对象 var obj = { 属性1:1 属性2:是, Property3:"测试", Property4:函数(值){返回true; }, Property5:函数(值){返回true; }, Property6:函数(值){返回true; }, Property7:函数(值){返回true; }, Property8:函数(值){返回true; }, Property9:函数(值){返回true; }, Property10:函数(值){返回true; }, Property11:函数(值){返回true; }, Property12:函数(值){返回true; }, Property13:函数(值){返回true; } }; logObject('Test',obj); /*设置HTTP响应*/ http.response.setContentType(http.ContentType.APPLICATION_JSON); http.response.setStatus(http.HttpStatus.HTTP_OK); http.response.setContent({result:'success'}); http.response.send(); } //在日志文件中记录对象。 如果property是函数-将其记录为'Func' 函数logObject(objName,obj) { var replacer =函数(键,值) { //如果属性是函数,则获取'Func'值 如果(typeof值==='函数') { 返回'Func'; } 返回值 }; var stringToLog =''; 尝试 { stringToLog = JSON.stringify(obj,replacer,2); } 赶上(exc) { stringToLog ='无法序列化对象'; } //日志字符串 console.log(objName +':'+ stringToLog); }
如果我调用此脚本,则会收到以下响应:
{ "错误":{ "代码":511, "信息": { " lang":" zh-cn", ""值":"脚本错误:编译错误[SyntaxError:意外的标识符]。" } } }
如果我在POST函数中移动函数的逻辑,一切都会顺利进行。
示例3:
此错误可能与进入点之外的函数和变量有关,但我对结果感到非常惊讶。 这是我的脚本文字:
//需要必要的实体 //需要处理http调用 var http = require('HttpModule.js'); //调用SL实体/动作是必需的 var ServiceLayerContext = require('ServiceLayerContext.js'); //实体代理对象 var Customer = require('EntityType/BusinessPartner'); //结果对象 var result = { IsSuccess:是的, ErrorMsg:", BookingSapCode:'', CustomerSapCode:" }; //输入对象的验证器 var inputValidator = { BookingId:函数(值){返回true; }, BookingSapCode:函数(值){返回true; }, IsCanceled:函数(值){返回true; }, 日期:函数(值){返回isNaN(Date.parse(value)); }, 电子邮件:函数(值){返回true; }, 电话:函数(值){返回true; }, CustomerId:函数(值){返回true; }, 标题:函数(值){返回true; }, 名称:函数(值){返回true; }, 姓:函数(值){返回true; }, CustomerSapCode:函数(值){返回true; }, CustomerSapSeries:函数(值){返回true; }, 详细信息:函数(值) { //检查是否为数组 如果(!Array.isArray(value))返回false; //实例化SL上下文 var slContext = new ServiceLayerContext(); //对于每个ItemCode检查此项目是否存在 value.forEach(函数(元素) { 如果(!checkItemCode(element.SapItemCode,slContext))返回false; }); 返回true; } }; //===================================进入点=========== =======================================// 函数GET(){ } 函数DELETE(){ } 函数PATCH(){ } 函数POST(){ console.log('开始执行'); //获取请求的正文 logObject('val',inputValidator); var inputObject = getBody(inputValidator); logObject('inputObj',inputObject); //记录输入对象以检查数据 /*设置HTTP响应*/ http.response.setContentType(http.ContentType.APPLICATION_JSON); http.response.setStatus(http.HttpStatus.HTTP_OK); http.response.setContent(result); http.response.send(); } //===================================私人功能========== =======================================// 函数checkItemCode(itemCode,slContext) { 返回true; } //===================================常见功能=========== =======================================// //获取主体并通过传递的"验证器"验证结构。 //验证器将所有属性显示为验证函数 函数getBody(validator) { //尝试从身体获取数据 var jsonObj = http.request.getJsonObj(); 如果(!jsonObj) { 抛出http.ScriptException(http.HttpStatus.HTTP_BAD_REQUEST,"无法从请求有效内容中获取JSON格式的内容"); } //只有存在变量 如果(typeofvalidator!=='undefined') { var错误= validateObject(jsonObj,验证器); logObject('错误',错误); 如果(errors.length> 0) { 抛出http.ScriptException(http.HttpStatus.HTTP_BAD_REQUEST,"输入对象无效:" + errors.join('|')); } } //返回反序列化的主体 返回jsonObj; } //通过模式验证对象 函数validateObject(object,schema){ var错误= Object.keys(模式) .map(功能(属性) { varvalidator = {}; //属性的验证函数 var isMissing = false; if(object [property] === undefined)//如果object没有此属性-函数总是返回false { 验证程序=函数(值){return false}; isMissing = true; } 其他 { 验证者=模式[属性]; //获取验证功能 } return {property:property,isValid:validator(object [property]),isMissing:isMissing}; }) .reduce(功能(错误,属性检查) { 如果(propertyCheck.isValid ===否) { errors.push(propertyCheck.property +(propertyCheck.isMissing?"丢失。":"无效。")); } 返回错误; },[]); 返回错误; } //在{SL Installation Path}/logs/script/*中记录对象 函数logObject(name,obj) { var replacer =(键,值)=> { //如果有函数,请给我们该函数的代码 如果(typeof值==='函数') { 返回'Func'; } 返回值 }; //检查是否没有序列化错误 var stringToLog =''; 尝试 { stringToLog = name +':'+ JSON.stringify(obj,replacer,2); } 赶上(exc) { stringToLog = name +':无法序列化-'+排除; } //日志字符串 console.log(stringToLog); }
所以,我的想法是我要验证我的请求正文。 为此,我使用方法而不是属性声明了一个蓝图对象。 这种方法检查我的请求对象的数据。
但是,我总是会遇到一些缺少某些字段的异常情况。 这是我的回复:
{ "错误":{ "代码":600, "信息": { " lang":" zh-cn", " value":"输入对象无效:缺少CustomerSapSereries。" } } }
但是我的架构对象中没有 CustomerSapSereries 属性。 因此,在测试期间,当我更改了一些代码段时(以我与此观点无关的拙见),我将一些属性重命名了(用Titltle代替Title和CustomerSerieses而不是CustomerSeries)。 这确实使我感到困惑,我很高兴对以下行为的原因做出任何澄清。
更新:
我猜想serviceLayerContext的问题是因为此变量在引擎中使用。
function getContextHandle(){ 返回serviceLayerContext; }
嗨,Ralph,
感谢您的回答! 如果您不介意,我对您的答案还有其他疑问。
示例1:
谢谢,当我检查现有模块时,已经澄清了一点。 有保留的变量名称列表吗? 我敢打赌,这不是唯一会引发错误的人。 如果您可以与社区共享此列表,以防止脚本出现意外行为,我将不胜感激。
示例2:
感谢我在文档中没有找到任何限制的指针。 因此,如果我想重用一些代码块,比如说在POST和PATCH之间,我可以声明一个函数变量吗? 那是唯一的方法吗? 顺便说一句,我可以为此使用箭头功能吗? 喜欢:
相同的东西,但是我不确定它是否得到正式支持。
示例3:
那只是一个例子。 我想在服务器上添加此检查,以确保JSON是正确的,以防止更改客户端但忘记服务器的任何错误。 那只是一种情况,如果我可以使用变量但不能使用函数,我仍然可以做到这一点。
在此先感谢您。
一周热门 更多>