【问题标题】:ERROR: INVALID_RESPONSE - Data is returning from promise but can't get Alexa to speak/show card错误:INVALID_RESPONSE - 数据从承诺返回,但无法让 Alexa 说话/显示卡
【发布时间】:2019-05-24 16:11:38
【问题描述】:

我在nodejs中有两个https请求,第一个是确认用户被授权访问数据,第二个是返回数据。

我有控制台日志,我看到数据已成功返回到承诺中,但 Alexa 不会说话/显示卡片。 cloudwatch 中没有错误。

我不完全理解 Promise 语法,所以我确定我遗漏了一些简单的东西。

我一直在更改语法,尝试 async/await,但似乎没有任何效果。

编辑的代码 - 在一些帮助下,我能够更好地布置我的代码。我现在在云手表中收到错误:错误:INVALID_RESPONSE,向技能分派请求时发生异常。

注意:出现此错误是因为我现在正在强制执行错误,也就是顶部(如果 redacted.errors)。

messages.NO_ACCESS 当前设置为 ----“嗯,您似乎无权访问该数据。”

const IntentRequest = {
    canHandle(handlerInput) {
        return handlerInput.requestEnvelope.request.type === 'IntentRequest';
    },
    handle(handlerInput) {
        const { requestEnvelope, serviceClientFactory, responseBuilder } = handlerInput;
        let resp, resultData;

    return new Promise((resolve, reject) => {
         checkAuthenticationStatus(handlerInput, function(json){

            if(REDACTED.errors) {
                console.log('unauthed', REDACTED.error)
                reject(handlerInput.responseBuilder.speak(messages.NO_ACCESS).withSimpleCard('Unauthorized Request', messages.NO_ACCESS).getResponse());

            } else if(REDACTED.noerror && REDACTED.noerror.data == 'true'){
                const url = new URL(REDACTED.url);

               const resp = httpsGetIntent(handlerInput, url, (theResult) => {
                    resultData = theResult;
                    console.log('resolved with ---->', d)
                    return resolve(handlerInput.responseBuilder.speak("The result was" + d).withSimpleCard('Hello World', d).getResponse());
                })

            }

        })

        });

    },
};

这是返回数据的部分代码(resultData 和 d 是相同的东西,都返回数据),但她不说话/出示卡片:

const IntentRequest = {
    canHandle(handlerInput) {
        return handlerInput.requestEnvelope.request.type === 'IntentRequest';
    },
     handle(handlerInput) {
        const { requestEnvelope, serviceClientFactory, responseBuilder } = handlerInput;
        let resp, resultData;
        return new Promise((resolve, reject) => {
            checkAuthenticationStatus(handlerInput, function(json){
                if(REDACTED) {
                reject(handlerInput.responseBuilder.speak(messages.NO_ACCESS).withSimpleCard('Unauthorized Request', messages.NO_ACCESS).getResponse())

            } else if(REDACTED && REDACTED == 'true'){
                const url = new URL(REDACTED);

                resp = httpsGetIntent(handlerInput, url, (theResult) => {
                    resultData = theResult;
                    console.log(resultData)
                }).then((d) => { 
                    console.log(d)
                    resolve(handlerInput.responseBuilder.speak("The result was" + d.response.outputSpeech.text).withSimpleCard('Hello World', d.response.outputSpeech.text).getResponse());
                }).catch((err) => { console.log(err)});

            }

        });

        });

    },
};

【问题讨论】:

    标签: node.js lambda es6-promise alexa-skills-kit


    【解决方案1】:

    您需要考虑一些问题,但问题中并不清楚。

    这里删除了什么,该值从何而来?你没有在任何地方提到它。

    为了方便,我们假设它是一个全局变量。

    如果 REDACTED 出于任何原因为假,那么您的代码将永远不会执行。因为条件永远不会满足。所以这个承诺既不会拒绝也不会解决。

    如果我假设你在第一个 if 语句中错误地写了 REDACTED,它应该是 !REDACTED。

     resp = httpsGetIntent(handlerInput, url, theResult => {
                  resultData = theResult;
                  console.log(resultData);
                })
                .then(d => {
                  console.log(d);
                  resolve(
                    handlerInput.responseBuilder
                    .speak("The result was" + d.response.outputSpeech.text)
                    .withSimpleCard("Hello World", d.response.outputSpeech.text)
                    .getResponse()
                  );
                })
                .catch(err => {
                  console.log(err);
                });
    

    这里 httpsGetIntent 也不正确,您有一个接收 theResult 的回调方法,但附加了一个 then 方法,这没有任何意义。此外,resultData 在这里没有做任何事情。

    假设 checkAuthenticationStatushttpGetIntent 都有回调模式,你可以这样写

    const IntentRequest = {
      canHandle(handlerInput) {
        return handlerInput.requestEnvelope.request.type === "IntentRequest";
      },
      handle(handlerInput) {
        const {
          requestEnvelope,
          serviceClientFactory,
          responseBuilder
        } = handlerInput;
        let resp, resultData;
        return new Promise((resolve, reject) => {
    
          checkAuthenticationStatus(handlerInput, function (json) {
            if (!REDACTED) {
              reject(
                handlerInput.responseBuilder
                .speak(messages.NO_ACCESS)
                .withSimpleCard("Unauthorized Request", messages.NO_ACCESS)
                .getResponse()
              );
            } else if (REDACTED && REDACTED == "true") {
              const url = new URL(REDACTED);
    
              httpsGetIntent(handlerInput, url, theResult => {
                resultData = theResult;
                console.log(resultData);
               return resolve(
                  handlerInput.responseBuilder
                  .speak("The result was" + d.response.outputSpeech.text)
                  .withSimpleCard("Hello World", d.response.outputSpeech.text)
                  .getResponse()
                );
              })
            }
          });
        });
      }
    };
    

    【讨论】:

    • 谢谢!抱歉不清楚 - 我只是不想共享敏感数据/数据结构。这是来自我的身份验证函数的 json 响应,顶部是它是否返回错误,底部是它是否返回身份验证 + 数据,用于路由第二个请求的位置。我根据您所说的进行了更新,现在收到“错误:INVALID_RESPONSE,向技能发送请求时发生异常。”我将在上面更新我的代码
    • 谢谢!我理解你的担心。您实际上可以发布虚拟代码:)
    • 我更新了上面的代码,与您建议的格式相匹配,并提供了有关已编辑的更多信息。 REDACTED 是从 checkAuthenticationStatus 回调 (json) 传回的值
    • 错误:INVALID_RESPONSE,向技能分派请求时发生异常。
    • 你能调试代码吗?还有一件事REDACTED && REDACTED == "true" 这是故意的权利
    【解决方案2】:

    在箭头符号中,.then((d) => resolve(x)) 将返回解析,因为对解析的调用在同一行,但如果你 .then(() => { // more than one line }) 我认为你只需要显式调用 return

    const IntentRequest = {
      canHandle(handlerInput) {
        return handlerInput.requestEnvelope.request.type === 'IntentRequest';
      },
      handle(handlerInput) {
        const { requestEnvelope, serviceClientFactory, responseBuilder } = handlerInput;
        // do you need resp here?
        let resp, resultData;
        return new Promise((resolve, reject) => {
          checkAuthenticationStatus(handlerInput, function(json){
            // does REDACTED know about json?
            if(!REDACTED) {
              reject(handlerInput.responseBuilder
                .speak(messages.NO_ACCESS)
                .withSimpleCard('Unauthorized Request', messages.NO_ACCESS)
                .getResponse());
            } else if(REDACTED && REDACTED == 'true') {
              const url = new URL(REDACTED);
              httpsGetIntent(handlerInput, url, (resultData) => {
                console.log(resultData);
                return resultData;
              }).then((d) => {
                resolve(handlerInput.responseBuilder
                  .speak("The result was" + d.response.outputSpeech.text)
                  .withSimpleCard("Hello World", d.response.outputSpeech.text)
                  .getResponse());
              }).catch((err) => { console.log(err)});
            }
          });
        });
      }
    },
    

    【讨论】:

    • 谢谢!我只是在它之前添加了回报,但似乎没有任何改变。 @本胡兰
    猜你喜欢
    • 2020-10-15
    • 2020-09-21
    • 2019-02-06
    • 1970-01-01
    • 2021-01-04
    • 1970-01-01
    • 1970-01-01
    • 2019-04-21
    • 2015-03-14
    相关资源
    最近更新 更多