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

提升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响应报错原因及修复

核心问题

  1. 错误未阻断后续流程:你在Axios请求的.catch里仅打印错误,但没有终止后续的.then逻辑。当API请求失败(比如限流、超时)时,.then仍会执行,此时res是undefined,自然无法读取res.data。
  2. 无限制并发请求:map配合async/await会一次性发起所有请求,当数量达到30+时,很可能触发API的限流机制,导致大量请求失败,进而引发上述报错。

修复方案

  • 改用try/catch替代.then/.catch,错误发生时直接跳过后续逻辑;
  • 控制请求并发数,比如用串行处理或分批并行,避免触发API限流。

二、数据库连接过多原因及修复

核心问题

  1. 无限制并发数据库操作:每个记录的更新请求都是独立发起的,当查询限制为50时,会同时创建50个数据库连接,超出了PostgreSQL默认的连接池大小(通常默认10个左右)。
  2. 未等待异步操作完成: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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 18:30:59