NodeJS - Promise回调响应[SyntaxError:意外的输入结束]

时间:2016-06-22 22:35:18

标签: node.js rest promise asynccallback unexpectendoffile

我创建了以下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调用以在Imperva系统中创建新的OS连接IP)。

  httpHelp(options, data)
  .then(function(fullResponse){
    var result = JSON.parse(fullResponse[1])

如上所述,只要httpHelp(选项,数据).then(function(fullResponse){...}部分被调用,如果我打印( console.log("任何&#) 34;))在下一行之前,它显示该消息正常。但是,在以下行之后没有打印,原因: fullResponse [1] 没有得到填充或不获取任何有效值,到以下行执行异步方式时。这导致程序直接进入.fail(...){..}部分,然后它将进入someFunc3(在impvaCreateIP期间它没有做任何异常捕获,最后到达.catch(...){..}部分并做我在那里做的任何事情。

    var result = JSON.parse(fullResponse[1])

因此,字符的 .parse 程序错误,即它无法为变量结果PARSE任何东西 as fullResponse [1] 值仍设置为"" (空白/空)并且尚未填充。

如何,我可以让我的程序等待,直到httpHelp(..)。then(function(fullResponse){....}完全使用REST / API调用完成并返回一个有效的值 fullResponse [1]

PS:我看到fullResponse [0] .statusCode == 200,所以连接正常。

代码:

//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;
}
如果someFunc1 / 3或ImpervaCreateIP是,则

fullResponse (数组值的快照)。我只显示最后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行,您将看到第235行结束fullResponse [0]数组索引值,而行#236启动fullResponse的值[1]并且有一个'' (空白/ NULL),这意味着,在使用impervaCreateIP创建IP时, DID NOT 在fullResponse [1]数组索引中接收来自Imperva REST / API的有效响应,该索引由

var result = JSON.parse(...); // line in my NodeJS code above.

同样,someFunc1(查找IP)或impervaCreateIP(创建IP)之间唯一的主要区别是,除此之外,只有console.log(" ...")消息更改为位:

对于impervaCreateIP,它设置为:

method: 'POST',

对于someFunc1,它设置为:

method: 'GET',

好的,似乎问题就在于,我的方法 POST / DELETE + 当我使用 var result = JSON.parse(fullResponse [1])

如果我没有尝试使用var result / JSON.parse检查任何内容,如上所述,我的代码工作正常。

所以,我认为我的根本原因是:如果我的REST / API HTTP方法是 POST DELETE 。如果我 DON' 使用任何状态检查,比如在someFunc3中的impervaCreateIP(POST操作)之后发生的事情(即,方法为DELETE的impervaDeleteSessionID),那么我的程序工作正常,我的错误消息消失了。

但是,我确实想验证REST回复的内容 for ex :这样我就可以了解REST连接是否有效+如果由于权限问题导致创建IP操作失败对于那些用于生成我的JSESSIONID凭据的用户。我只有在POST / DELETE和我正在做JSON.parse(fullResponse [1])

时才得到ERROR

当HTTP方法为" POST"时,如何在上述NodeJS代码中获取响应主体?或"删除"我想抓住一个条件,如下所述?? 谢谢。

FYI : 当我在BASH shell脚本中尝试相同的impervaCreateIP NodeJS逻辑时,我编写了以下代码并且它可以工作!如果由于该用户的凭证的访问问题而在创建IP脚本创建期间出现错误,则CURL命令返回所有OUTPUT好或坏,即具有有效响应代码。 在NodeJS代码中尝试的所有内容都是为了捕获" 没有权限"如果用户没有足够的权限在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 个答案:

答案 0 :(得分:0)

我会深入潜水,回答你为什么你的假设是关于"快速完成而不是回归"是错的。

javascript的体系结构不允许在返回之前调用异步回调。

javascript在一个线程上有一个堆栈,该函数被推入堆栈,执行并在之后弹出。你不能一次在堆栈上做两件事。

当javascript遇到异步操作时,它通过c ++ libuv库将操作推送到另一个线程,然后当异步操作完成时,操作返回到javascript上的一个叫做回调队列的东西。只有当堆栈为空时,事件队列中的事物才被推送到堆栈,通过"事件循环"。因此,返回值总是首先执行,因为触发异步函数的函数仍然占用javascript堆栈,直到遇到返回并且函数从堆栈弹出,使其清晰并准备接受回调队列中的内容。

尝试记录fullResponse,看一下它是否有fullResponse[1]