【问题标题】:Alexa sdk v2 using ask-sdk-core custom skill fails with : Session ended with reason: ERROR使用 ask-sdk-core 自定义技能的 Alexa sdk v2 失败:会话以原因结束:错误
【发布时间】:2018-12-30 01:31:22
【问题描述】:

我正在开发一种自定义技能,但在这个意图上遇到了一些麻烦,也就是说,在 if/else 控制流中满足所有条件的最后阶段,我的意思是当它到达最后一个 else 时声明,只有这一个未能返回预期的响应,但所有返回的响应都工作得很好,我可能在这里遗漏了什么:请密切注意最后一部分 resolve(handlerInput.responseBuilder.speak....etc )。我不确定我在这里做什么,我会很感激

const SetDefaultLocationIntentInProgress = {
      canHandle(handlerInput) {
        return handlerInput.requestEnvelope.request.type === 'IntentRequest'
        && handlerInput.requestEnvelope.request.intent.name === 'SetDefaultLocationIntent';
      }, 
       handle(handlerInput) {
        console.log(`In SetDefaultLocationIntentInProgress`);
        let cardTitle = speech.getCardTitle('setdefaultloc1');

        let city = '';
        let state = '';
        let zipcode = '';


        const { attributesManager, responseBuilder } = handlerInput;
        const sessionAttributes = attributesManager.getSessionAttributes();

        const currentIntent = handlerInput.requestEnvelope.request.intent;


        if (sessionAttributes[currentIntent.name]) {
            const tempSlots = sessionAttributes[currentIntent.name].slots;
            for (const key in tempSlots) {
                if (tempSlots[key].value && !currentIntent.slots[key].value) {
                    currentIntent.slots[key] = tempSlots[key];
                }
            }
        }

        sessionAttributes[currentIntent.name] = currentIntent;
        attributesManager.setSessionAttributes(sessionAttributes);

        if (currentIntent.slots.City && currentIntent.slots.City.value) {
            // User provided value for City slot
            city = currentIntent.slots.City.value;
        }

        if (currentIntent.slots.State && currentIntent.slots.State.value) {
            // User provided value for State slot
            state = currentIntent.slots.State.value;
        }

        if (currentIntent.slots.Zipcode && currentIntent.slots.Zipcode.value) {
            // User provided value for Zipcode slot
            zipcode = currentIntent.slots.Zipcode.value;
        }

        debugLog(`City: ${city}, State: ${state}, Zipcode: ${zipcode}`);

        let speechOutput = '';
        let repromtText = '';

        if (city.length === 0 && state.length === 0 && zipcode.length === 0) {
            // No values provided by user for city, state or zipcode
            speechOutput = speech.getSpeechText('setdefaultloc5');
            repromtText = speech.getSpeechText('reprompt2');
            return handlerInput.responseBuilder
            .speak(speechOutput)
            .reprompt(repromtText)
            .withSimpleCard(cardTitle, speechOutput)
            .withShouldEndSession(false)
            .getResponse();
        }else if(zipcode.length > 0 && !zipCodeValidator(zipcode) ) {
            // user provided a zipcode but it is not a valid US zipcode
            let speechObject = speech.getSpeechObject('setdefaultloc7');
            speechOutput = util.format(speechObject.text, zipcode);
            repromtText = speech.getSpeechText('reprompt3');
            return handlerInput.responseBuilder
            .speak(speechOutput)
            .reprompt(repromtText)
            .withSimpleCard(cardTitle, speechOutput)
            .withShouldEndSession(false)
            .getResponse();

        }else {

            let params = '';
            let lookupFunc = '';
            let placeNameLookup = '';
            if (zipcode.length > 0 && zipCodeValidator(zipcode)) {
                params = zipcode;
                lookupFunc = apiCalls.zipcodeLookup;
            }else {
                if (state.length === 0) {
                    params = city;
                    placeNameLookup = city;
                }else{
                    params = `${city}+${state}`;
                    placeNameLookup = `${city} ${state}`;
                }
                lookupFunc = apiCalls.placeNameLookup;
            }

            lookupFunc (params,  (error, result, duration) => {

                if(error || result === null) {
                    // API Call failed or result is null 
                    speechOutput = speech.getSpeechText('error2', false);
                    repromtText = speech.getSpeechText('reprompt3', false);

                    return handlerInput.responseBuilder
                    .speak(speechOutput)
                    .reprompt(repromtText)
                    .withSimpleCard(cardTitle, speechOutput)
                    .withShouldEndSession(false)
                    .getResponse();
                }else if (Object.keys(result).length === 0) {
                    // Returned an empty result
                    if (zipcode.length > 0) {
                        // was zipcode 
                        let speechObject = speech.getSpeechObject('setdefaultloc4');
                        repromtText = speech.getSpeechText('reprompt3', false);


                        speechOutput = util.format(speechObject.text, zipcode);

                    }else{
                        // wasn't zipcode
                        let speechObject = speech.getSpeechObject('setdefaultloc3');

                        repromtText = speech.getSpeechText('reprompt3', false);

                        speechOutput = util.format(speechObject.text, zipcode);

                    }
                    return handlerInput.responseBuilder
                        .speak(speechOutput)
                        .reprompt(repromtText)
                        .withSimpleCard(cardTitle, speechOutput)
                        .withShouldEndSession(false)
                        .getResponse();
                }else {
                    // Api Call successfull with result objects length > 0
                    return new Promise( (resolve, reject) => {
                        handlerInput.attributesManager.getPersistentAttributes()
                            .then((attributes) => {
                                const defaultLoc = {
                                    name: result.name,
                                    lat: result.lat,
                                    lon: result.lon
                                };
                                const userId = handlerInput.requestEnvelope.context.System.user.userId;
                                attributes['defaultLoc'] = defaultLoc;

                                debugLog("Writing attributes to DynamoDB: " + userId + ", " + "defaultlocation: " + JSON.stringify(defaultLoc));
                                handlerInput.attributesManager.setSessionAttributes(attributes);
                                handlerInput.attributesManager.setPersistentAttributes(attributes);
                                handlerInput.attributesManager.savePersistentAttributes();

                                let speechObject = speech.getSpeechObject('setdefaultloc22');
                                repromtText = speech.getSpeechText('reprompt3', false);

                                speechOutput = util.format(speechObject.text, zipcode);

                                debugLog(`SpeechOutput After saving user location: ${speechOutput}`);

                                debugLog(`handlerInput: ${handlerInput.responseBuilder
                                    .speak(speechOutput)
                                    .reprompt(repromtText)
                                    .withShouldEndSession(false)
                                    .getResponse()}`);

                            resolve(handlerInput.responseBuilder.speak(speechOutput)
                                .reprompt(repromtText)
                                .withShouldEndSession(false)
                                .getResponse());
                            })
                            .catch((error) => {
                                console.log(`Error in SetDefaultLocationIntent promise: ${error}`);
                                reject(error);
                            });
                    });

                }
            });
        }

      },
  };

【问题讨论】:

  • 您可以尝试打印出您收到的错误消息吗?您可以将此代码添加到会话结束请求处理程序并发布它返回的消息吗? console.log(`Error occured: ${handlerInput.requestEnvelope.request.error.type}, ${handlerInput.requestEnvelope.request.error.message}`)
  • 感谢@R.Vait 的回复,因为error.type 和error.message 不是不可访问,所以显示错误,

标签: javascript node.js alexa alexa-skills-kit alexa-skill


【解决方案1】:

终于解决了这个问题:这只是一个我没有正确处理的 promise 问题,我不得不将 else 语句中的所有内容都包装在一个 promise 中,这就是我重组最后一个 else 语句的方式得到想要的结果。

else {
            return new Promise((resolve, reject) => {
                let params = '';
                let lookupFunc = '';
                let placeNameLookup = '';
                if (zipcode.length > 0 && zipCodeValidator(zipcode)) {
                    params = zipcode;
                    lookupFunc = apiCalls.zipcodeLookup;
                }else {
                    if (state.length === 0) {
                        params = city;
                        placeNameLookup = city;
                    }else{
                        params = `${city}+${state}`;
                        placeNameLookup = `${city} ${state}`;
                    }
                    lookupFunc = apiCalls.placeNameLookup;
                }

                    lookupFunc (params,  (error, result, duration) => {

                        if(error || result === null) {
                            // API Call failed or result is null 
                            speechOutput = speech.getSpeechText('error2', false);
                            repromtText = speech.getSpeechText('reprompt3', false);

                             resolove(handlerInput.responseBuilder
                                .speak(speechOutput)
                                .reprompt(repromtText)
                                .withSimpleCard(cardTitle, speechOutput)
                                .withShouldEndSession(false)
                                .getResponse());
                        }else if (Object.keys(result).length === 0) {
                            // Returned an empty result
                            if (zipcode.length > 0) {
                                // was zipcode 
                                let speechObject = speech.getSpeechObject('setdefaultloc4');
                                repromtText = speech.getSpeechText('reprompt3', false);


                                speechOutput = util.format(speechObject.text, zipcode);

                            }else{
                                // wasn't zipcode
                                let speechObject = speech.getSpeechObject('setdefaultloc3');

                                repromtText = speech.getSpeechText('reprompt3', false);

                                speechOutput = util.format(speechObject.text, zipcode);

                            }
                            resolve(handlerInput.responseBuilder
                                .speak(speechOutput)
                                .reprompt(repromtText)
                                .withSimpleCard(cardTitle, speechOutput)
                                .withShouldEndSession(false)
                                .getResponse());
                        }else {
                            // Api Call successfull with result objects length > 0
                                handlerInput.attributesManager.getPersistentAttributes()
                                    .then((attributes) => {
                                        const defaultLoc = {
                                            name: result.name,
                                            lat: result.lat,
                                            lon: result.lon
                                        };
                                        const userId = handlerInput.requestEnvelope.context.System.user.userId;
                                        attributes['defaultLoc'] = defaultLoc;

                                        debugLog("Writing attributes to DynamoDB: " + userId + ", " + "defaultlocation: " + JSON.stringify(defaultLoc));
                                        handlerInput.attributesManager.setSessionAttributes(attributes);
                                        handlerInput.attributesManager.setPersistentAttributes(attributes);
                                        handlerInput.attributesManager.savePersistentAttributes();

                                        let speechObject = speech.getSpeechObject('setdefaultloc22');
                                        repromtText = speech.getSpeechText('reprompt3', false);

                                        speechOutput = util.format(speechObject.text, zipcode);

                                        debugLog(`SpeechOutput After saving user location: ${speechOutput}`);

                                        debugLog(`handlerInput: ${handlerInput.responseBuilder}`);

                                        resolve(handlerInput.responseBuilder.speak(speechOutput)
                                            .reprompt(repromtText)
                                            .withShouldEndSession(false)
                                            .getResponse());
                                    })
                                    .catch((error) => {
                                        console.log(`Error in SetDefaultLocationIntent promise: ${error}`);
                                        reject(error);
                                    });

                        }
                    });

            });        
        }

【讨论】:

    猜你喜欢
    • 2018-12-12
    • 1970-01-01
    • 2018-12-03
    • 2018-11-02
    • 1970-01-01
    • 1970-01-01
    • 2018-09-24
    • 1970-01-01
    • 2017-03-28
    相关资源
    最近更新 更多