即使在捕获之后,Node.js仍然处于未处理状态
我正在使用节点7.2.1与新的asynchronous/等待function。 我也用这样的mongoose使用本地ES6诺言 –
const mongoose = require('mongoose'); mongoose.Promise = global.Promise;
我的代码stream是这样的 –
async function getFollowers(){ try { const followers = await User.getFollowersFromMongo(req.params.userId); res.send(followers); } catch (err) { winston.error('Printing Error = ', err); res.status(400).send({success: false, error: err}); } } UserSchema.statics.getFollowersFromMongo = async(userId) => { try { let aggregateQuery = []; //some syntactical error in mongo query to produce exception const followers = await User.aggregate(aggregateQuery); return followers.map(follower => follower.followerData); } catch (err) { return Promise.reject(err); } };
这段代码工作得很好。 出现错误时会出现问题。 所以我特意修改了我的mongoose查询,这样MongoDB就会抛出一个错误。
现在,MongoDB,如预期的抛出一个错误,完全被我的代码捕获,并返回给客户端400错误代码。
问题是即使错误(故意的)被我抓住了, Node.js仍然给了我这个警告 –
error: Printing Error = MongoError: path option to $unwind stage should be prefixed with a '$': followerData at Function.MongoError.create (/home/node_modules/mongodb-core/lib/error.js:31:11) at /home/node_modules/mongodb-core/lib/connection/pool.js:483:72 at authenticateStragglers (/home/node_modules/mongodb-core/lib/connection/pool.js:429:16) at Connection.messageHandler (/home/node_modules/mongodb-core/lib/connection/pool.js:463:5) at Socket.<anonymous> (/home/node_modules/mongodb-core/lib/connection/connection.js:317:22) at emitOne (events.js:96:13) at Socket.emit (events.js:188:7) at readableAddChunk (_stream_readable.js:176:18) at Socket.Readable.push (_stream_readable.js:134:10) at TCP.onread (net.js:551:20) GET /user/385/followers 400 39.868 ms - 263 (node:10158) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): MongoError: path option to $unwind stage should be prefixed with a '$': followerData (node:10158) DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
由于可以看到我的请求已经返回了400状态,而且我的错误日志也是从初始方法的catch块中打印出来的,但是Node.js仍然在说错误消息没有被处理。
为什么即使在发现相同的错误之后,也是这样说的?
更新 –感谢@dvlsg和@Bergi,这个bug在4.7.5版本中得到了修复
看起来似乎有什么奇怪的mongoose聚合如何与asynchronous/等待。 好像是一个bug,对我来说。 如果是的话,一定要报告mongoose。
谢天谢地,有一个简单的工作:
const followers = await User.aggregate(aggregateQuery).exec();
添加明确的.exec()
允许我按预期捕获聚合pipe道错误。
我认为这里增加了一个混乱的根本问题是,有一个额外的Promise
,其中正在被拒绝,而不是处理。 因为在技术上,你正在处理预期的拒绝。 否则,你不会看到Printing error = ...
被logging。
这是我相信正在发生的事情 –
- 你
await User.aggregate()
-
Aggregate#then()
通过await
与thenables
(我认为) -
Aggregate#exec()
由Aggregate#then()
内部调用Aggregate#then()
- 请注意, 提供给
exec()
的callbackexec()
- 请注意, 提供给
-
Aggregate#exec()
新Promise
被创build ,并被拒绝- 我相信这是未处理的
Promise
。
- 我相信这是未处理的
- 由于callback是从
Aggregate#then()
提供给Aggregate#exec()
Aggregate#then()
,Aggregate#exec()
的Error
将被提供给callbackAggregate#exec()
- 在
Aggregate#then()
的callback中,新创build的Promise
被拒绝- 我相信这个
Promise
是按预期处理的,因为它是来自Aggregate#then()
的回报,Aggregate#then()
- 我相信这个
我想我可以通过在mongooseAggregate
定义中注释这一行来证实我的怀疑。 这将防止未处理的拒绝处理程序被击中。 顺便说一下,我并不打算这样做。 这只是额外的证据,而不是一个解决scheme,因为现在我只是有一个不受欢迎的Promise
浮出水面。
这是一个最小化的方法来重现在一个自包含的代码中的未被捕获的拒绝,要与node --harmony-async-await
一起运行(在节点v7.2.1
上testing)
const mongoose = require('mongoose'); mongoose.Promise = global.Promise; mongoose.connect('mongodb://localhost/temp'); const userSchema = new mongoose.Schema({ name: 'string' }); const User = mongoose.model('User', userSchema); async function run() { try { await User.aggregate([]); } catch (err) { console.log('caught expected error:', err); } } run();
- asynchronous并等待一些IDE的错误
- Mongooseasynchronous/等待与Koa卡住await Model.findOne()。exec()
- 节点asynchronous/等待 – 我需要尝试/赶上?
- 在Node.js中使用TypeScriptasynchronous等待
- 在Node中处理嵌套asynchronous等待调用的正确方法是什么?
- Koa中的asynchronous函数奇怪的问题
- asynchronous/等待请求内部护照策略
- validation使用Mocha / Chai和asynchronous/等待引发exception
- 在Node.JS中使用async / await进行适当的请求