Alexa Skill error - PullRequest
       4

Alexa Skill error

0 голосов
/ 26 мая 2018

Я пытаюсь вызвать сторонний API в моем навыке Alexa, и в журнале 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]);
  });
}

1 Ответ

0 голосов
/ 27 мая 2018

Я полагаю, что вам нужно будет позвонить решить с вашим ответом в httpGet.

В качестве дополнительного примечания (не связанного с вашей проблемой) - я могу порекомендовать использовать запрос-обещание, он реализует очень хороший API-интерфейс обещания вокругhttp и упростит ваш код в этом случае.(Я знаю, что знаю, async / await - это новые и забавные инструменты, но в этом случае я бы выбрал «проще» :)).

Кроме того, если я правильно помню, обратный вызов для http.getвызывается только с одним аргументом.

edit, после изменений:

вы можете избавиться от обещания и асинхронности, чтобы упростить ваш код.Просто примечание по async / await - если выражение await ed не является обещанием, оно автоматически преобразуется в одно.В вашем текущем коде вам нужно либо использовать его как обещание (например, цепочку .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
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...