Node.js服务Mongoose连接场景下try-catch块可处理哪些错误?
问题原因分析
你现在的try-catch捕获不到错误,核心是两个问题:
connectDB内部已经自行捕获了mongoose连接错误,且捕获后仅打印日志、没有重新抛出错误,相当于把错误“吞掉”了。所以你await connectDB()得到的永远是成功状态的Promise,自然不会触发外层catch。app.listen是基于回调/事件的异步API,本身不会返回Promise,它的运行错误(比如端口被占用)会通过error事件抛出,同步的try-catch无法捕获这类非Promise的异步错误。
该try-catch可捕获的错误类型
它并非只能捕获主动抛出的错误,只要满足以下两类情况的错误都能被捕获:
try块内的同步运行时错误:比如你写错了变量名、调用了不存在的方法这类同步执行阶段抛出的错误,不管是你主动throw的还是JS运行时/依赖库自动抛的都能抓到。await后面的Promise返回rejected状态的错误:只要被await的Promise抛出reject,不管是异步IO错误、依赖库返回的错误还是主动抛的,都能被捕获。
你现在抓不到mongoose连接错误,只是因为connectDB里的catch把错误拦截了,没有往上抛。
修复方案
1. 调整connectDB的错误处理
要么删掉内部的catch,要么在catch内重新抛出错误,让外层能收到:
const connectDB = (url) => { return mongoose.connect(url, { useNewUrlParser: true, useUnifiedTopology: true }) .then(() => console.log('Connected to database')) .catch(err=>{ console.log(`DB CONNECTION ERR ${err}`) // 重新抛出错误,外层才能捕获 throw err }) }
2. 包装app.listen为Promise,才能被await捕获错误
// 封装app.listen为返回Promise的方法 const startServer = (port) => { return new Promise((resolve, reject) => { const server = app.listen(port) server.on('listening', () => resolve(server)) server.on('error', (err) => reject(err)) }) } // 调整start逻辑 const start = async () => { try { await connectDB(mongoURI) await startServer(port) console.log(`Server running at ${port}`) } catch (error) { console.log('服务启动失败,捕获到错误:', error); } }
调整后你再模拟连接错误、端口占用错误,都能被外层catch捕获到。
内容的提问来源于stack exchange,提问作者anandsr-dev
相关产品推荐
相关产品推荐

