Google Cloud自定义实体Fulfillment报错:Definicion属性读取失败
解决Dialogflow Fulfillment中"Cannot read property 'Definicion' of undefined"错误
我帮你分析下问题出在哪,以及怎么修复这个报错:
错误根源拆解
- 数组索引误用:Datastore的
runQuery返回的results[0]是匹配到的实体数组,下标从0开始。你用results[0][1]是取第二个实体,但如果查询只返回1个结果(甚至没结果),这个位置就是undefined,自然没法访问Definicion属性。 - 预定义查询的冗余与局限性:你提前创建了固定查'artritis'的
disease1查询,但代码里又做了疾病类型判断,完全可以根据用户输入动态构建查询,既灵活又避免冗余。 - 缺少参数与异常校验:没先检查
conv.parameters[DISEASE_TYPE_ENTITY]是否存在,万一用户输入没匹配到实体,直接调用.toLowerCase()也会报错;同时没处理查询无结果或Datastore调用异常的情况。
修复后的完整代码
'use strict'; const functions = require('firebase-functions'); const { dialogflow } = require('actions-on-google'); const datastore_enfermedades = require('@google-cloud/datastore'); const datastore = datastore_enfermedades(); const WELCOME_INTENT = 'Default Welcome Intent'; const FALLBACK_INTENT = 'Default Fallback Intent'; const LOOKING_FOR_DISEASE_INTENT = 'InfoDisease'; const DISEASE_TYPE_ENTITY = 'TypeDisease'; const app = dialogflow(); app.intent(WELCOME_INTENT, (conv) => { conv.ask('Hola! Si quieres puedo darte más información sobre alguna enfermedad, pregúntame!'); }); app.intent(FALLBACK_INTENT, (conv) => { conv.ask('Ai, no te he entendido, ¿puedes repetirmelo por favor?'); }); app.intent(LOOKING_FOR_DISEASE_INTENT, async (conv) => { // 先校验参数是否存在,避免后续报错 const disease_type = conv.parameters[DISEASE_TYPE_ENTITY]; if (!disease_type) { conv.ask("No he podido identificar la enfermedad que mencionas, ¿puedes repetirla por favor?"); return; } const normalizedDisease = disease_type.toLowerCase(); // 根据用户输入动态构建查询 const query = datastore.createQuery('Tabla de enfermedades') .filter('Enfermedad', '=', normalizedDisease); try { const [entities] = await datastore.runQuery(query); // 处理查询无结果的情况 if (entities.length === 0) { conv.ask(`Lo siento, no tengo información sobre ${normalizedDisease}. ¿Quieres preguntar sobre otra enfermedad?`); return; } // 取第一个匹配的实体(假设每个疾病名在Datastore中是唯一的) const diseaseData = entities[0]; conv.ask(diseaseData.Definicion); } catch (error) { // 捕获Datastore调用异常,给用户友好提示 console.error('Error al consultar Datastore:', error); conv.ask('Ha ocurrido un error al buscar la información, por favor intenta más tarde.'); } }); exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);
关键优化点
- 动态查询构建:不再硬编码查询条件,根据用户输入的疾病名生成查询,适配更多场景。
- 参数与结果校验:提前检查实体参数是否存在,同时处理查询无结果的情况,避免空值访问报错。
- 改用async/await:相比Promise链式调用,代码逻辑更直观易读。
- 异常捕获:添加try/catch块处理Datastore调用可能出现的异常,避免服务崩溃。
另外建议你检查Datastore中Tabla de enfermedades实体的Enfermedad字段值,确保和用户输入(转换为小写后)完全匹配,因为Datastore的过滤是大小写敏感的。
内容的提问来源于stack exchange,提问作者MariaGon
相关产品推荐
相关产品推荐

