我正在尝试在我的Alexa技能中调用第三方API,并且在CloudWatch日志中收到“会话终止,原因:错误”。问题似乎出在我的NumberIntentHandler或httpGet函数中,但是我不确定在哪里。

更新的代码

-被解雇的处理程序-

  const NumberIntentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && handlerInput.requestEnvelope.request.intent.name === 'NumberIntent';
  },
  handle(handlerInput) {
      let slotNum = handlerInput.requestEnvelope.request.intent.slots.number.value;
      //var myRequest = parseInt(slotNum);
      const myRequest = parseInt(slotNum);
      console.log('NumberIntentHandler myRequest: ', myRequest);
      var options = `http://numbersapi.com/${myRequest}`;
      console.log('NumberIntentHandler options: ', options);

      // Use the async function
  const myResult = httpGet(options);
         console.log("sent     : " + options);
         console.log("received : " + myResult);
         const speechText = myResult;
         console.log('speechText: ', speechText); // Print the speechText   */

      return handlerInput.responseBuilder
           .speak(speechText)
           .withSimpleCard('Here is your fact: ', speechText)
           .getResponse();
  },
};


-从处理程序调用的函数-

  async function httpGet(options) {
  // return new pending promise
  console.log(`~~~~~~~~~ httpGet ~~~~~~~~~`);
  console.log(`~~~~~${JSON.stringify(options)}~~~~~`);
  return new Promise((resolve, reject) => {

  const request = http.get(options, (response) => {
      // handle http errors
      if (response < 200 || response > 299) {
        reject(new Error('Failed to load page, status code: ' + response));
      }// temporary data holder
      const body = [];
      // on every content chunk, push it to the data array
      response.on('data', (chunk) => body.push(chunk));
      // we are done, resolve promise with those joined chunks
      response.on('end', () => resolve(body.join('')));
      console.log('body: ', body[0]);
    });
    // handle connection errors of the request
    request.on('error', (err) => reject(err));
    request.end();
  });
}


更新的代码-消除了异步/等待/承诺

-处理程序-

const NumberIntentHandler = {
  canHandle(handlerInput) {
    return handlerInput.requestEnvelope.request.type === 'IntentRequest'
      && handlerInput.requestEnvelope.request.intent.name === 'NumberIntent';
  },
  handle(handlerInput) {
      let slotNum = handlerInput.requestEnvelope.request.intent.slots.number.value;
      //var myRequest = parseInt(slotNum);
      const myRequest = parseInt(slotNum);
      console.log('NumberIntentHandler myRequest: ', myRequest);
      var options = `http://numbersapi.com/${myRequest}`;
      console.log('NumberIntentHandler options: ', options);

      // Use the async function
  //const myResult = httpGet(options);
    const myResult = httpGet(options, res => {

         console.log("sent     : " + options);
         console.log("received : " + myResult);
         const speechText = myResult;
         console.log('speechText: ', speechText); // Print the speechText   */

      return handlerInput.responseBuilder
           .speak(speechText)
           .withSimpleCard('Here is your fact: ', speechText)
           .getResponse();
    });
  },
};


-功能-

function httpGet(options, cb) {
  http.get(options, res => {
    console.log(`~~~~~${JSON.stringify(options)}~~~~~`);
    // simplified version without error handling
    let output = [];
    res.on('data', d => output.push(d)); // or concat to a string instead?
    res.on('end', () => cb(output));
    console.log('output: ', output[0]);
  });
}

最佳答案

我相信您需要在httpGet中使用您的回复来调用resolve。

作为附带说明(与您的问题无关)-我可以建议您使用请求承诺,它在http周围实现了一个非常不错的promise API,在这种情况下将简化您的代码。 (我知道我知道,异步/等待是新的有趣的工具,但在这种情况下,我会选择“更简单” :))。

另外,如果我没记错的话,http.get的回调仅使用一个参数被调用。

更改后进行编辑:

您可以摆脱诺言和异步来简化您的代码。
只是关于async / await的注释-如果awaited表达式不是promise,那么它将自动转换为一个。在您当前的代码中,您需要像应诺一样使用它(例如,链接.then())或等待它。

无论如何,这是一个仅使用回调的示例:

function httpGet(options, cb) {
  http.get(options, res => {
    // simplified version without error handling
    let output = [];
    res.on('data', d => output.push(d)); // or concat to a string instead?
    res.on('end', () => cb(output));
  });
}

httpGet(options, res => {
// building the alexa response, all your intent handler code that needs the response from your request
})

关于javascript - Alexa技能错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50545631/

10-09 20:13