Node.js中Hapi与MySQL异步(async/await)调用无返回结果问题排查
问题分析与修复方案
核心问题
- Promise与回调混用:你已经通过
util.promisify把pool.query转为Promise风格,但仍传入了回调函数。此时await拿到的不是回调里返回的结果数组,而是回调函数本身,直接导致返回值无法正确传递给客户端。 - SQL注入风险:直接拼接
state参数到SQL语句中,存在严重安全漏洞。 - 错误处理缺失:
async函数中抛出的错误未被捕获,无法返回合法的HTTP错误响应给客户端。
修复后的Handler代码
method: "GET", path: "/getCountyByState/{state}", handler: async function (request, h) { // 建议将require移到文件顶部,避免每次请求重复加载模块 const pool = require("./database-promise"); const state = request.params.state; // 使用参数化查询避免SQL注入 const sql = 'select county_name from static_web_data.state_counties where state_name = ?'; try { const results = await pool.query(sql, [state]); if (results && results.length > 0) { // 用map简化结果转换逻辑 const countyList = results.map(item => item.county_name); return countyList; } else { return h.response("404 Error! Page Not Found!").code(404); } } catch (err) { console.log("Query threw exception: " + err); return h.response("Database query error").code(500); } },
关键修改说明
- 移除回调函数:
await pool.query(sql, [state])直接返回查询结果,无需传入回调,结果会被赋值给results变量。 - 参数化查询:用
?作为占位符,参数放在数组中传入,彻底规避SQL注入风险。 - try/catch捕获错误:捕获查询过程中的异常,返回500错误响应给客户端,同时保留错误日志便于排查。
- 简化结果处理:用
Array.map替代forEach+push的写法,代码更简洁;通过results.length > 0判断是否有数据,比typeof results !== "undefined"更准确。
额外优化建议
- 将
const pool = require("./database-promise");移到文件顶部,不要在handler内部重复加载模块,提升请求处理性能。 - 可以把错误响应标准化为JSON格式,比如
return h.response({ error: "Database query error" }).code(500);,方便前端统一处理。
内容的提问来源于stack exchange,提问作者Not a machine
相关产品推荐
相关产品推荐

