不会捕获从mongoose承诺的callback函数抛出的错误

我花了太多时间试图弄清楚为什么我的express.js控制器没有响应一个简单的查询,并且发现从一个Mongoose-promisecallback触发的运行时错误正在默默地中断callback过程。

这里是我的代码的简化版本:

server.get('/api/test', function (req, res, next) { User.find({}).exec().then(function success(users){ console.log('SUCCESS'); typo[0] = 1; // throws a runtime error res.json(users); }, function error(err){ console.log('ERROR'); res.json({error: err}); }); }); 

这导致SUCCESS在我的控制台显示,但没有任何反应。 没有给予用户的回应,我的错误造成的错误没有出现在我的控制台,错误callback也不会被调用。

我知道一个人不应该从callback函数中抛出exception,但是在这种情况下,这只是一个错字,而且当我这样做的时候,我会被警告(比如标准输出中的堆栈跟踪)的错误。 (毕竟我们是人类)

在你看来,当承诺callback中出现这种错误时,获得反馈的最佳方式是什么?

这是Mongoose使用错误承诺实现的错。 承诺是安全的,所以exception被捕获(所以他们可以在以后的代码处理) – 未来的代码永远不会到来,mongoose从来没有报告过它没有。 良好的承诺实现不会遇到这个问题。

你的select是两个:

使用像蓝鸟这样的图书馆:

 var Promise = require("bluebird"); var mongoose = Promise.promisifyAll(require("mongoose")); User.findAsync({}).then(function(data){ JSON.prase("dsa"); // not a silent failure, will show up, easy debugging }); 

这具有比mongoose承诺更快的优点,所以不存在性能损失。 另外,如果你是超级保守的,不想要蓝鸟的性能和API收益 – 你可以使用原生的承诺:

 // Promise is the native promise Promise.resolve(User.find({}).exec()).then(function(data){ JSON.prase("dsa"); }); 

然后,假设您正在运行nodejs的一个现代变体(请阅读:io.js v 1.4.1或更高版本),您可以订阅承诺拒绝:

 process.on("unhandledRejection", function(p, why){ console.log("FOUND ERROR!!!!", p , why); }); 

所以例外情况并没有被默默地压制。

exec()有两个承诺

 .then(function) .then(null , function) 

试试这个,我认为这会有所帮助

 server.get('/api/test', function(req, res, next) { User.find({}).exec() .then(function success(users) { console.log('SUCCESS'); typo[0] = 1; // throws a runtime error res.json(users); }) .then(null, function error(err) { console.log('ERROR'); res.json({ error: err }); }); });