【问题标题】:Alexa Skill Lambda returns, but Alexa says Invalid ResponseAlexa Skill Lambda 返回,但 Alexa 说无效响应
【发布时间】:2020-10-15 03:57:55
【问题描述】:

场景:

我有一个支持 Alexa Skill 的 Node.JS 12.x Lambda。用户向技能提出问题,搜索参数被发送到我的 Lambda 插槽中。我使用 mssql 包查询 SQL DB,然后将结果返回给用户。

问题:

如果我从数据库中获取结果,Lambda 会成功执行查询并返回结果,但是 Lambda 会超时,Alexa 似乎没有收到响应。如果我删除数据库查询并只返回一个字符串,一切正常。

怀疑:

我认为这里的 async/await 内容可能存在一些问题。我只是无法弄清楚问题是什么。我已经检查了我多次使用 async/await

如果我遗漏了什么,请告诉我。提前致谢!

代码:

/**
 * Intent handler for FindSomething intent
 */
const MyHandler = {
    /**
     * Determine whether this handler is able to process this input
     * @param {Object} handlerInput The input object
     */
    canHandle(handlerInput) {
        // This part works fine
        return util.checkIntentMatch(handlerInput, INTENT_NAME);
    },

    /**
     * Handle the input
     * @param {Object} handlerInput The input object
     */
    async handle(handlerInput) {
        // Extract slot values
        const [
            searchTerm,
        ] = [
            Alexa.getSlotValue(handlerInput.requestEnvelope, 'search_term'),
        ];

        // Fulfill request
        const responseText = await getResponseText(searchTerm);

        // Respond
        return handlerInput.responseBuilder
            .speak(responseText)
            .getResponse();
    },
};

然后getResponseText 看起来像这样:

/**
 * Get the response text for the query
 * @param {string} searchTerm The search term from the user
 */
async function getResponseText(searchTerm) {
    let sectorName = await getSectorForTerm(searchTerm);
    console.log(`Inside getResponseText.  sectorName: ${sectorName}`);

    if (!sectorName) return format(NOT_FOUND_LANGUAGE, { searchTerm });

    return format(FOUND_LANGUAGE, { searchTerm, sectorName });
}

/**
 * Find the sector for a search term
 * @param {string} searchTerm The search term from the user
 */
async function getSectorForTerm(searchTerm) {

    // ========================================================================
    // If I uncomment this line, it works great -- all the way back to the user
    // ========================================================================
    //return 'fake result';

    // Gather prerequisites in parallel
    let [
        query,
        pool
    ] = await Promise.all([
        fs.readFile(path.join(__dirname, 'queries', 'FindQuery.sql'), 'utf8'),
        sql.connect(process.env['connectionString'])
    ]);

    console.log('Pre query');

    // Run query
    let queryResult = await pool.request()
        .input('EntityName', sql.TYPES.VarChar, searchTerm)
        .query(query);

    console.log('Post query');

    // Extract result if any
    let result = undefined;
    if(queryResult.recordset.length > 0) {
        result = queryResult.recordset[0]['SectorName'];
    }

    console.log(`result of getSectorForTerm: ${result}`);

    return result;
}

编辑:

这是日志的样子。您可以看到文件已加载,查询已执行,并且在 ~500 毫秒内命中了返回语句。然后在函数超时之前经过几秒钟。

编辑 2:

我已经像 AWS 文档中的这个示例一样构建了我的 index.js,因此我无法直接访问 context 或类似内容。如果需要,可以更改。

【问题讨论】:

    标签: alexa-skills-kit alexa-skill


    【解决方案1】:

    您在技能中使用了 2 个耗时的操作 - 文件读取和 sql 连接。可能你的技能超过了 8 秒超时。如果有类似的消息,请查看与您的技能相关的 CloudWatch 日志

    Task timed out after 8.01 seconds
    

    您应该在此处进行一些改进。 还要确保 Promise.all 参数中的两个方法都返回一个 Promise。

    【讨论】:

    • 感谢您的回答。我的操作根本不需要太多时间。我已经在日志中验证了该文件已被读取,并且查询结果在调用后约 500 毫秒内返回。为了清楚起见,我已将带有时间安排的日志添加到我的问题中。
    • 还有游泳池,你不应该关闭它吗?
    • 我考虑并研究了它,并确定这应该基于两个原因工作:我以这种方式编写的其他 lambdas 工作正常,mssql 文档显示以这种方式编写的示例代码。我假设池在后台处理了我的 mssql。为了更好地衡量,我尝试添加pool.close() 和类似的,但它仍然无法正常工作。另请参阅我关于context.success 建议的问题的补充
    • 原来我需要await pool.close()。我忘了这是一个承诺。不知道为什么我的其他 Lambda 在没有明确关闭池的情况下工作(并且他们的自述文件中的示例代码没有说你需要关闭它),但这似乎出于某种原因在这里起到了作用。 npmjs.com/package/mssql#asyncawait
    猜你喜欢
    • 1970-01-01
    • 2019-07-15
    • 2017-04-11
    • 2019-11-09
    • 2018-01-21
    • 1970-01-01
    • 2020-05-04
    • 2016-04-24
    • 1970-01-01
    相关资源
    最近更新 更多