Alexa技能读取托管文本文件报SpeechletResponse was null错误
问题根因
报错核心是异步Promise逻辑存在缺陷,具体有3个问题:
- Promise未正确返回结果:在
response.on('end')事件回调里直接写return text是无效的,事件回调的返回值会被直接丢弃,代码里从来没有调用resolve(text)把异步结果传给Promise,导致await reader.readFile()会一直挂起,后面构造Alexa响应的代码永远不会执行。Alexa服务端等不到技能返回的响应,超时后就会抛出INVALID_RESPONSE: SpeechletResponse was null错误。 - 响应存储变量全局污染:把
text变量定义在了模块最外层,不是每次调用readFile时独立初始化的,多次调用接口时会出现新老内容拼接串扰的问题。之前能在控制台看到打印的响应内容,是上一次调用残留的全局变量值被意外输出,实际上那次调用的Promise根本没走完流程。 - 错误监听覆盖不全:只监听了response对象的错误,没有监听request对象本身的网络错误(比如连接失败、超时),这类错误会直接触发未捕获异常,导致技能崩溃。
修复方案
修复readFile异步逻辑
把全局的text变量移到Promise内部,在end事件里正确调用resolve返回结果,补全request的错误监听:
const https = require('https'); module.exports = { readFile: (host, path) => { return new Promise((resolve, reject) => { // 每次调用独立初始化文本存储,避免全局污染 let text = ''; const options = { host: host, path: path, method: 'GET', }; const request = https.request(options, (response) => { response.setEncoding('utf8'); response.on('data', (chunk) => { text += chunk; }); response.on('end', () => { // 正确触发resolve,把结果返回给await resolve(text); }); response.on('error', (error) => { reject(error); }); }); // 补全request层面的错误监听 request.on('error', (error) => { reject(error); }); request.end(); }); } };
给意图处理器增加异常捕获
避免请求失败时技能直接返回空响应:
const InformacionIntentHandler = { canHandle(handlerInput) { return handlerInput.requestEnvelope.request.type === 'IntentRequest' && handlerInput.requestEnvelope.request.intent.name === 'InformacionIntent'; }, async handle(handlerInput) { try { const fileContent = await reader.readFile('res.cloudinary.com','/fdgdfg/raw/upload/v1656032273/fofo_mbbjr0.txt'); console.log('获取到的文件内容:', fileContent); return handlerInput.responseBuilder .speak("Okay. Here is what I got back from my request. " + fileContent) .reprompt("What would you like?") .getResponse(); } catch (err) { console.error('请求远程文件失败:', err); return handlerInput.responseBuilder .speak("Sorry, I failed to get the information right now. Please try again later.") .getResponse(); } }, };
修复效果
- 接口请求完成后Promise会正常返回结果,await后续的响应构造逻辑会正常执行,不会再出现响应为null的错误
- 每次请求的内容独立存储,不会出现多次调用内容串扰的问题
- 网络错误、请求错误都会被捕获,返回友好提示,不会直接中断会话
内容的提问来源于stack exchange,提问作者Omar Cravioto
相关产品推荐
相关产品推荐

