[英]Alexa sdk v2 using ask-sdk-core custom skill fails with : Session ended with reason: ERROR
我正在开发一种自定义技能,并且对此意图有一些麻烦,也就是说,在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);
});
});
}
});
}
},
};
终于解决了问题: 这只是我未正确处理的诺言问题 ,我不得不将一切都包裹在else语句中,这就是我如何重组最后的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);
});
}
});
});
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.