mssql流模式下查询无schema表触发未捕获异常无法捕获问题
问题原因
- 代码事件绑定存在作用域错误:
client是mssql.connect()异步返回的实例,client.on('error')被定义在then回调外部,此时client还未初始化,该事件监听器未成功绑定,导致连接层面抛出的错误没有被捕获。同样finally块中访问的client也属于未定义变量,无法正常关闭连接。 - mssql v7.2.x版本的流模式存在已知逻辑缺陷:当SQL执行报错时,错误除了会触发
readStream的error事件外,还会被底层tedious驱动二次抛出到连接实例上,未成功绑定连接错误监听的情况下就会变成未捕获异常。 Invalid object name报错的根本原因:未指定schema时,mssql会默认使用当前登录用户的默认schema,如果该schema下没有对应表,就会抛出对象不存在错误。
解决方案
1. 修正事件绑定与作用域问题
将连接实例的错误监听、资源释放逻辑都移到异步回调内部,确保能正确绑定生效,参考修正后的代码:
import mssql from 'mssql'; import stream from 'stream'; import fs from 'fs'; import path from 'path'; // 全局兜底捕获(可选,用于避免极端情况导致进程退出) process.on('uncaughtException', (err) => { if (err.name === 'RequestError' && err.message.includes('Invalid object name')) { log.error('捕获到mssql查询错误', err); } else { throw err; } }); async function queryTable() { let client = null; try { client = await mssql.connect({ server, port: Number.parseInt(port), database, user, password, options: { encrypt: true, trustServerCertificate: Boolean(trustServerCertificate), // 新增:指定默认schema,不用每次写SQL都带schema前缀 schema: '你的schema名称' } }); // 绑定连接层面的错误监听 client.on('error', error => { log.error('SQL连接错误', error); }); const readStream = client.request(); readStream.stream = true; const passThroughStream = new stream.PassThrough(); const writeStream = fs.createWriteStream(path.join(__dirname, './writeMe.json')); readStream.on('error', (err) => log.info('查询流错误', err)); passThroughStream.on('error', (err) => log.info('转换流错误', err)); writeStream.on('error', (err) => log.info('写入流错误', err)); readStream.pipe(passThroughStream).pipe(writeStream); readStream.query(query); } catch (err) { log.info('捕获到同步/异步等待错误', err); } finally { if(client){ await client.close(); } } } queryTable(); // 全局mssql错误监听 mssql.on('error', error => { log.error('全局SQL错误', error); });
2. 修复表不存在问题
二选一即可:
- 所有SQL查询语句明确指定schema前缀,写法为
select * from [schema名称].[表名] - 直接在连接配置的
options中添加schema参数,指定默认使用的schema,后续查询不需要再写前缀
3. 版本兼容修复
如果上述操作后仍有未捕获异常,可以将mssql升级到v7.3.0以上的小版本,该版本修复了流模式下错误重复抛出的问题。
内容的提问来源于stack exchange,提问作者Oron Bendavid
相关产品推荐
相关产品推荐

