Node.js中MySQL连接池异常未捕获问题求助
问题分析与修复方案
1. 未等待异步执行,导致try/catch失效
在doProcess函数里调用insertNewRecord(record)时没加await,异步函数会直接跳过执行,外层的try/catch根本抓不到后续抛出的错误。
修复代码:
async function doProcess() { try { const record = { /* 你的记录数据 */ }; await insertNewRecord(record); // 加上await等待异步操作完成 } catch (error) { console.log(error); } }
2. 原生mysql包的pool.query不支持直接await
你用的原生mysql包是回调风格API,pool.query默认不会返回Promise,直接用await相当于无效操作,自然捕获不到错误。
解决方法一:用回调处理错误
function insertNewRecord(record, callback) { const connectionUrl = 'mysql://root:mypassword@mydatabasehost:3306/mydb'; const pool = mysql.createPool(connectionUrl); pool.on('connection', function (conn) { console.log('*******on connection***********'); }); pool.on('error', function (err) { console.log('****POOL CONNECTION ERROR***', err); }); pool.query('INSERT INTO users SET ?', record, (err, results) => { if (err) { console.log('Query error:', err); callback(err); return; } callback(null, results); pool.end(); // 用完池后关闭(全局池无需每次关闭) }); } async function doProcess() { try { const record = { /* 数据 */ }; await new Promise((resolve, reject) => { insertNewRecord(record, (err, res) => { err ? reject(err) : resolve(res); }); }); } catch (error) { console.log(error); } }
解决方法二:改用mysql2/promise(更适配异步/await)
mysql2提供了Promise化API,更符合你现在的写法习惯:
先安装依赖:
npm install mysql2
修改代码:
const mysql = require('mysql2/promise'); // 引入promise版本 async function insertNewRecord(record) { const connectionUrl = 'mysql://root:mypassword@mydatabasehost:3306/mydb'; const pool = mysql.createPool(connectionUrl); pool.on('connection', function (conn) { console.log('*******on connection***********'); }); pool.on('error', function (err) { console.log('****POOL CONNECTION ERROR***', err); }); try { await pool.query('INSERT INTO users SET ?', record); } finally { await pool.end(); // 全局池可省略此步骤 } } async function doProcess() { try { const record = { /* 你的记录数据 */ }; await insertNewRecord(record); } catch (error) { console.log('Process error:', error); } }
3. 重复创建连接池的不合理操作
你每次调用insertNewRecord都新建一个连接池,既浪费资源,还可能导致错误事件还没绑定就已经触发。连接池应该全局初始化一次,重复使用:
const mysql = require('mysql2/promise'); // 全局初始化连接池,只执行一次 const pool = mysql.createPool('mysql://root:mypassword@mydatabasehost:3306/mydb'); pool.on('connection', function (conn) { console.log('*******on connection***********'); }); pool.on('error', function (err) { console.log('****POOL CONNECTION ERROR***', err); }); async function insertNewRecord(record) { await pool.query('INSERT INTO users SET ?', record); } async function doProcess() { try { const record = { /* 数据 */ }; await insertNewRecord(record); } catch (error) { console.log(error); } }
4. 关于pool.on('error')的触发逻辑
池的error事件一般是在池内连接出现不可恢复的错误(比如连接断开且无法重连)时触发。像你这种首次连接就因为主机名错误失败的情况,错误会直接在query操作中抛出,不会触发池的error事件,所以必须通过try/catch捕获query的错误,不能只依赖池的事件监听。
内容的提问来源于stack exchange,提问作者lecarpetron dookmarion
相关产品推荐
相关产品推荐

