如何在Node.js/Express/MySQL中从AWS Parameter Store获取数据库凭证及报错解决
问题解决:从AWS Parameter Store获取数据库凭证+修复
pool.query is not a function错误 1. 直接从SSM拿凭证是可行的
没必要把凭证存到dotenv文件,直接从AWS Parameter Store拉取更安全,能避免敏感信息落地,你的思路没问题。
2. 错误根源:pool不是实际的连接池实例
你把pool定义成了一个async函数:let pool = async () => await dbConnection();,但dbConnection()返回的是Promise,所以pool本身是个函数,不是MySQL连接池对象,调用pool.query自然会报“不是函数”的错误。
3. 修正后的代码及说明
完整修正代码
require('dotenv').config() const AWS = require('aws-sdk'); const ssm = new AWS.SSM({ region: 'us-east-1', }); const mysql = require('mysql'); // 存储连接池初始化的Promise,确保只执行一次 let poolPromise; async function getSSMParameter(param) { try { const parameter = await ssm.getParameter({ Name: param, WithDecryption: true }).promise(); return parameter.Parameter.Value; } catch (err) { console.error('获取SSM参数失败:', err); throw err; // 抛出错误让上层处理,避免后续代码拿到undefined } } async function initDBPool() { const pw = await getSSMParameter('pw-d'); return mysql.createPool({ connectionLimit: 10, host: "xxxxxxxx", user: "xxxxxxxxxxx", password: pw, database: "xxxxxxxxxxxx" }); } // 提前初始化连接池Promise,避免每次调用executeSQL都重新拉取凭证 poolPromise = initDBPool(); async function executeSQL(sql, params) { // 先拿到实际的连接池实例 const pool = await poolPromise; return new Promise((resolve, reject) => { pool.query(sql, params, (err, rows, fields) => { if (err) { reject(err); // 用reject传递错误,符合Promise规范 return; } resolve(rows); }); }); } module.exports = { executeSQL };
关键修正点:
- 重命名
key函数为getSSMParameter,并在catch块抛出错误,防止后续代码因parameter为undefined崩溃 - 用
poolPromise存储连接池初始化的Promise,确保只从SSM拉取一次凭证,避免重复请求 - 在
executeSQL里先通过await poolPromise拿到实际的连接池实例,再调用query方法 - 将
executeSQL里的throw err改为reject(err),遵循Promise错误处理的正确方式
4. async/await使用小提醒
- async函数的返回值永远是Promise,不能直接把async函数当作普通值使用
- 必须用
await获取async函数的实际返回值,且await只能在async函数内部使用 - 涉及await的代码尽量用try/catch包裹,避免出现未捕获的Promise错误
内容的提问来源于stack exchange,提问作者user20577101
相关产品推荐
相关产品推荐

