提升psql数据库查询限制后Axios请求失败,求排查原因
问题描述
我写了一个从PostgreSQL数据库获取记录,再通过Axios调用API验证的函数。当数据库查询限制设为10时运行正常,但提升到30及以上时,会抛出错误:const status = res.data.data.status; TypeError: Cannot read properties of undefined (reading 'data')
另外,即使限制为10,运行结束后数据库会提示too many connections for role "DBNAME"。请问哪里操作有误?
const verify = async () => { console.log("Reading data from DB for verification..."); await pool .query( ` SELECT * FROM main_leads WHERE hunter_uploaded = FALSE AND email_sent = 'false' AND verification is NULL limit 50 ` ) .then((data) => { const emails = data.rows.map(async (x) => { await axios({ method: "GET", url: `Verify`, }) .catch((err) => { console.log(err.message); }) .then(async (res) => { console.log(res.data.data); const status = res.data.data.status; // console.log(status); console.log(`${res.email}:` + " " + res.status); // await pool.query( `UPDATE main_leads SET domain_processed = TRUE, verification = $1 WHERE ID = $2`, [status, x.id] ); }); }); }); }; verify();
问题分析与解决
一、Axios响应报错原因及修复
核心问题
- 错误未阻断后续流程:你在Axios请求的
.catch里仅打印错误,但没有终止后续的.then逻辑。当API请求失败(比如限流、超时)时,.then仍会执行,此时res是undefined,自然无法读取res.data。 - 无限制并发请求:
map配合async/await会一次性发起所有请求,当数量达到30+时,很可能触发API的限流机制,导致大量请求失败,进而引发上述报错。
修复方案
- 改用
try/catch替代.then/.catch,错误发生时直接跳过后续逻辑; - 控制请求并发数,比如用串行处理或分批并行,避免触发API限流。
二、数据库连接过多原因及修复
核心问题
- 无限制并发数据库操作:每个记录的更新请求都是独立发起的,当查询限制为50时,会同时创建50个数据库连接,超出了PostgreSQL默认的连接池大小(通常默认10个左右)。
- 未等待异步操作完成:
map返回的Promise数组没有被await,导致连接池无法及时回收连接,最终引发连接耗尽报错。
修复方案
- 控制数据库操作的并发数,比如用串行处理(适合低并发场景)或分批并行;
- 确保所有异步操作都被正确等待,让连接池能及时回收连接。
修正后的完整代码
const verify = async () => { console.log("Reading data from DB for verification..."); try { // 先查询需要处理的记录 const { rows } = await pool.query(` SELECT * FROM main_leads WHERE hunter_uploaded = FALSE AND email_sent = 'false' AND verification is NULL limit 50 `); // 串行处理每条记录,避免并发过高(若需更高性能可改用分批Promise.all) for (const row of rows) { try { // 发起API验证请求 const apiRes = await axios({ method: "GET", url: `Verify` // 注意这里需替换为完整的API地址 }); const status = apiRes.data.data.status; console.log(`ID ${row.id} 验证状态: ${status}`); console.log(`${row.email} 请求状态: ${apiRes.status}`); // 更新数据库记录 await pool.query(` UPDATE main_leads SET domain_processed = TRUE, verification = $1 WHERE ID = $2 `, [status, row.id]); } catch (err) { console.error(`处理ID ${row.id} 失败:`, err.message); // 标记该记录为验证错误,避免重复处理 await pool.query(` UPDATE main_leads SET domain_processed = TRUE, verification = 'error' WHERE ID = $1 `, [row.id]); } } console.log("所有记录处理完成"); } catch (dbErr) { console.error("数据库查询失败:", dbErr.message); } finally { // 若程序结束不再使用连接池,可关闭释放所有连接 // await pool.end(); } }; verify();
内容的提问来源于stack exchange,提问作者Vinn
相关产品推荐
相关产品推荐

