You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js中Hapi与MySQL异步(async/await)调用无返回结果问题排查

问题分析与修复方案

核心问题

  1. Promise与回调混用:你已经通过util.promisify把pool.query转为Promise风格,但仍传入了回调函数。此时await拿到的不是回调里返回的结果数组,而是回调函数本身,直接导致返回值无法正确传递给客户端。
  2. SQL注入风险:直接拼接state参数到SQL语句中,存在严重安全漏洞。
  3. 错误处理缺失: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 20:32:54