我创建了以下NodeJS函数 .
我得到的问题是,当我执行这样的代码时:
someFunc(parameter)
.then(function(doSomething){
//do something here, which works fine here.
})
//The following function works and is very similar to the next function.
.then(someFunc1)
//
.then(impervaCreateIP)
//
//The following function works and is very similar to the above function.
.then(someFunc3)
.catch(function(e){
//catch error here. This works too.
})
并调用下面的函数,它给了我一个错误:
[SyntaxError: Unexpected end of input]
出现此错误是因为,当函数(someFunc1)成功完成后控件转到 impervaCreateIP() ,然后在impervaCreateIP()内部,执行以下行(等待REST / API调用以创建新的OS连接IP)在Imperva系统中) .
httpHelp(options, data)
.then(function(fullResponse){
var result = JSON.parse(fullResponse[1])
如上所示,只要调用httpHelp(选项,数据).then(function(fullResponse)部分,如果我在下一行之前打印( console.log("anything") ),它就会显示该消息正常 . 但是,在以下行之后没有打印,原因: fullResponse[1] 没有得到填充或没有获得任何有效值,到以下行执行异步方式时 . 这导致程序直接进入.fail(...) 部分,然后它's going to someFunc3 (where it'没有做任何事情作为异常捕获在impervaCreateIP期间,并最终到达.catch(...)部分并做我在那里做的任何事情 .
var result = JSON.parse(fullResponse[1])
因此,程序在 . 处出错 . 字符,即它不能为变量 result PARSE任何东西,因为 fullResponse[1] 值仍设置为“”(空白/空)并且尚未填充 .
如何,我可以让我的程序等待,直到httpHelp(..) . then(function(fullResponse)完全使用REST / API调用完成,并在 fullResponse[1] 内返回一个有效值 .
PS:我看到fullResponse [0] .statusCode == 200,所以连接正常 .
Code:
//Imperva create IP
//qData is a hash array that has valid index/value pair values.
var impervaCreateIP = function(qData){
var deferred = Q.defer();
var data = '{"connection-mode":"SSH","host-name":"server123.company.com"}'
var options = {
hostname: 'myImpervaServerInstance.mycompanydomain.com',
port: 8083,
method: 'POST',
path: '/SecureSphere/api/v1/conf/serverGroups/'+ qData['siteName'] + '/' + qData['serverGroupName'] + '/servers/' + qData['ip'],
headers: {
'Content-Type': 'application/xml',
'X-Requested-With': 'Nodejs',
'Cookie': 'JSESSIONID='+qData['sid']
}
}
//svtLog() is a logger that I'm using to log messages to a file. Out of scope of this post.
svtLog('info','Imperva','Inside impervaCreateIP function')
svtLog('info','Imperva',qData['ip'])
svtLog('info','Imperva',qData['siteName'])
svtLog('info','Imperva',qData['serverGroupName'])
console.log('Inside impervaCreateIP')
console.log(options);
httpHelp(options, data)
.then(function(fullResponse){
//The following section is not executing
console.log("00 ---- this will print fine")
var result = JSON.parse(fullResponse[1])
//The following section is not executing. It going straight to .catch() as the above line failed at .parse(fullResponse[1]) where fullResponse[1] is coming as BLANK.
console.log("11 -----")
console.log(result)
console.log("22 -----")
deferred.resolve(qData)
console.log(result)
})
.fail(function(e){
svtLog('error','Imperva','Failed to add IP in Imperva')
svtLog('info','Imperva',qData['ip'])
svtLog('error','Imperva',e)
svtLog('info','Imperva','')
deferred.reject(e)
})
return deferred.promise;
}
fullResponse (数组值的快照是)在someFunc1 / 3或ImpervaCreateIP的情况下 . 我只显示最后5行 . 我确保两个文件的头部-5看起来相同,而fullResponse [0]索引值也大致相似:
[vagrant@localhost ws]$ cat -n someFunc1.ip.fullResponse.json |tail -5; echo ----------------; cat -n create.ip.fullResponse.json |tail -5
230 parser: null,
231 res: [Circular] },
232 read: [Function] },
233 '{"ip":"10.20.30.40","domain":"","connection-mode":"SSH","share-name":"","folder-path":"","user-name":"enter_your_userID","host-name":"test-imperva-clientserver01.cloud.mycompany.com","OS-type":"Linux"}' ]
234
----------------
233 parser: null,
234 res: [Circular] },
235 read: [Function] },
236 '' ]
237
[vagrant@localhost ws]$
如果您注意到someFunc1.ip.fullResponse.json文件中的第232行和第233行,则第232行结束fullResponse [0],而行#233启动fullResponse [1]值 . 在我的例子中,假设someFunc1是找到一个IP,因此上面的输出显示,REST / API返回值fullResponse [1]值用于使用Imperva REST / API(其中方法是GET)查找IP,其余代码完全相似to impervaCreateIP() .
如果您注意到create.ip.fullResponse.json文件的第235行和第236行,则其中包含'll see that line# 235 ends fullResponse[0] array index value and line# 236 starts the value for fullResponse[1] and has a ''(空白/空),这意味着,在使用impervaCreateIP创建IP时,它会从Imperva REST接收有效响应/ fullResponse [1]中的API使用的数组索引
var result = JSON.parse(...); // line in my NodeJS code above.
同样,someFunc1(查找IP)或impervaCreateIP(创建IP)之间唯一的主要区别是,除此之外,只有console.log(“...”)消息有所改变:
对于impervaCreateIP,它设置为:
method: 'POST',
对于someFunc1,它设置为:
method: 'GET',
好的,所以看起来问题是,当我使用 var result = JSON.parse(fullResponse[1]) 时 method 是 POST / DELETE + .
如果我不尝试使用var result / JSON.parse检查任何内容,如上所述,我的代码工作正常 .
所以,我认为我的根本原因是:在我的REST / API HTTP方法是 POST 或 DELETE 的情况下,fullResponse [1]由于某种原因没有填充 . 如果我 DON'T 使用任何状态检查,比如在someFunc3期间在impervaCreateIP(POST动作) or 之后发生的事情(即,方法为DELETE的impervaDeleteSessionID),那么我的程序工作正常,我的ERROR消息就消失了 .
BUT, I do want to verify what REST responded back for ex :因此,如果由于我用于生成JSESSIONID的凭据的用户的权限问题导致创建IP操作失败,我可以捕获REST连接是否有效 . 我'm getting the ERROR only when its POST/DELETE and I'正在做JSON.parse(fullResponse [1])
How can I get the response body in the above NodeJS code, when HTTP method is "POST" or "DELETE" and I want to catch a condition as I mentioned below?? 谢谢 .
FYI :当我在BASH shell脚本中尝试相同的impervaCreateIP NodeJS逻辑时,我编写了以下代码并且工作正常!因为CURL命令返回所有OUTPUT的好坏,即如果在创建IP脚本期间由于该用户的凭据的访问问题而出现错误,则返回有效的响应代码 . NodeJS代码中的 All I'm trying to do 是为了捕获“ do not have permission ”错误,如果USER没有足够的权限在Imperva系统中创建IP,则可能会出现这种错误:
## Create a new IP OS connection in a given site, server group.
create_ip()
{
JSESSIONID="${1}"
addThisIP="${2}"
siteName="${3}"
serverGroupName="${4}"
echo -e "\n- Trying to create a new OS connection IP now.\n";
##Make sure while initiating a REST API call, any parameter which has ' ' (space) in Imperva should be substituted with '%20'.
create_new_ip_output="$(curl -ik -X POST -H "Cookie: JSESSIONID=$JSESSIONID" -H "Content-Type: application/json" -H "Accept: application/json" "https://${MX}:8083/SecureSphere/api/v1/conf/serverGroups/${siteName// /%20}/${serverGroupName// /%20}/servers/${addThisIP}" -d '{"connection-mode":"SSH","host-name":"thisLinuxServer.fdqn","OS-type":"linux","user-name":"enter_your_userID"}')";
return_code="$?";
if [[ "${return_code}" == "0" && ! `echo "${create_new_ip_output}" | grep "do not have permission"` ]]; then
echo -e "\n\n- OS connection IP (${addThisIP}) created successfully in site: ${siteName}, servergroup: ${serverGroupName} and stdout:\n${create_new_ip_output}\n";
return 0;
else
echo -e "\n\n- Failed to create a new OS connection IP (${addThisIP}) in site: ${siteName} and servergroup: ${serverGroupName}\n- using session ID: ${JSESSIONID}, error log:\n${create_new_ip_output}\n";
return 1;
fi
}
1 回答
我会深入潜水,回答你为什么你的“快速完成而不是回归”的假设是错误的 .
javascript的体系结构不允许在返回之前调用异步回调 .
javascript在一个线程上有一个堆栈,该函数被推入堆栈,执行并在之后弹出 . 你不能在堆栈上一次做两件事 .
当javascript遇到异步操作时,它通过c libuv库将操作推送到另一个线程,然后当异步操作完成时,操作返回到javascript上的一个叫做回调队列的东西 . 事件队列中的事物仅在堆栈为空时被“事件”推送到堆栈因此,返回值总是首先执行,因为触发异步函数的函数仍然占用javascript堆栈,直到遇到返回并且函数从堆栈弹出,使其清除并准备接受回调队列中的内容 .
尝试记录
fullResponse
,看它是否首先有fullResponse[1]
.