MySQL查询在try语句中仍致程序崩溃,如何处理undefined避免崩溃?
解决MySQL查询无结果时的程序崩溃与异步逻辑问题
我来帮你搞定这个问题,你的代码目前有两个核心问题需要修复,咱们一步步来:
1. 未处理查询结果为空的情况
当查询没有找到匹配的记录时,result会是一个空数组,这时候result[0]就是undefined,直接访问result[0].id自然会抛出Cannot read property 'id' of undefined的错误。你需要先判断result[0]是否存在,再去访问它的属性。
2. 异步操作的时机问题
con.query是异步执行的,这意味着你后面的if (message.author.id !== ... && blacklisted)代码会在查询完成之前就运行,此时blacklisted还是初始的false,完全达不到你想要的逻辑效果。必须把依赖blacklisted的逻辑放到查询回调内部,或者用Promise+async/await来处理异步流程。
修复方案一:改进回调写法
let blacklisted = false; const conStr = "SELECT * FROM `blacklist` WHERE `id` = ?"; // 用参数化查询避免SQL注入,更安全! con.query(conStr, [message.author.id], function(error, result, field) { // 先处理查询错误 if (error) { console.error('查询黑名单出错:', error); return; } // 检查是否有匹配记录 if (result[0]) { console.log("找到黑名单记录"); blacklisted = true; // 原代码逻辑疑似反转,这里根据需求调整:找到记录则标记为黑名单用户 } else { blacklisted = false; } // 把依赖blacklisted的逻辑放到回调里,确保查询完成后再执行 if (message.author.id !== "397487086522990602" && blacklisted){ // 这里写你的实际业务代码 console.log("执行黑名单限制逻辑"); } });
修复方案二:用Promise+async/await优化异步流程(更易读)
如果你的环境支持ES6+,推荐用这种方式,异步逻辑会更清晰:
// 先把con.query包装成Promise,方便用await处理 function queryBlacklist(userId) { return new Promise((resolve, reject) => { const conStr = "SELECT * FROM `blacklist` WHERE `id` = ?"; con.query(conStr, [userId], (error, result) => { if (error) reject(error); resolve(result); }); }); } // 用async函数封装整个逻辑 async function checkBlacklistAndRunLogic(message) { try { const result = await queryBlacklist(message.author.id); const blacklisted = !!result[0]; // 有记录就是黑名单用户,无则不是 if (message.author.id !== "397487086522990602" && blacklisted){ // 执行你的实际业务代码 console.log("执行黑名单限制逻辑"); } } catch (error) { console.error('查询黑名单出错:', error); } } // 调用函数触发逻辑 checkBlacklistAndRunLogic(message);
额外提醒:避免SQL注入
原代码里直接把message.author.id拼接到SQL字符串里,存在SQL注入风险,我在修复方案里用了参数化查询(?作为占位符,把参数放到数组里传递),这是更安全的写法,一定要养成这个习惯!
内容的提问来源于stack exchange,提问作者KillerDogeAlt
相关产品推荐
相关产品推荐

