Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 未捕获从mongoose promise回调函数引发的错误_Node.js_Express_Error Handling_Mongoose_Promise - Fatal编程技术网

Node.js 未捕获从mongoose promise回调函数引发的错误

Node.js 未捕获从mongoose promise回调函数引发的错误,node.js,express,error-handling,mongoose,promise,Node.js,Express,Error Handling,Mongoose,Promise,我花了太多时间试图弄清楚为什么我的express.js控制器没有响应一个简单的查询,并且弄清楚了从Mongoose promise回调引发的运行时错误正在悄悄地中断回调过程 以下是我的代码的简化版本: server.get('/api/test', function (req, res, next) { User.find({}).exec().then(function success(users){ console.log('SUCCESS'); typo[0] =

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

以下是我的代码的简化版本:

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
显示在我的控制台中,但随后什么也没有发生。没有响应给用户,由我的输入错误引起的错误没有出现在我的控制台中,错误回调也没有被调用

我知道不应该从回调函数中抛出异常,但在这种情况下,这只是一个输入错误,每当出现此类错误时,我都会收到警告(例如,标准输出中的堆栈跟踪)。(毕竟,我们是人类……)

在您看来,在promise回调中出现此类错误时,获得反馈的最佳方式是什么?

the
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
            });
        });
});

这是Mongoose使用坏承诺实现的错误。承诺是安全的,因此异常会被捕获(以便以后可以由未来的代码处理)——未来的代码永远不会出现,Mongoose也永远不会报告它没有出现。良好承诺的实现不会受到此问题的影响

你有两个选择:

使用像Bluebird这样的库:

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
});
这具有比猫鼬承诺更快的优势,因此不会造成性能损失。或者,如果您非常保守,不想获得bluebird的性能和API收益,您可以使用原生承诺:

// Promise is the native promise
Promise.resolve(User.find({}).exec()).then(function(data){
    JSON.prase("dsa");
});
然后,假设您运行的是现代版本的nodejs(读:io.jsv1.4.1或更高版本),您可以订阅承诺拒绝:

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

因此,异常不会被默默地抑制

不,它不工作。=><代码>类型错误:对象#没有方法“catch”对不起,我更新了我的答案,在promise的调用类型中,mongoose和sequelize之间存在冲突。我相信
exec()。catch(handler)
类似于
exec()。然后(null,handler)
在承诺的一般情况下。。。。使用两个
then()
相当于将成功和错误回调组合到同一个
then()
。cf=>它不能解决问题。区别在于
。然后是(handler)。然后是(null,handler)
。然后是(handler,handler2)
这就是我将“投掷安全”称为“投掷危险”的原因。错误被承诺代码捕获,并被“吞没”。幸运的是,错误也在传播。要使其可见,请尝试在承诺链的末尾添加一个
.catch()
,并记录错误。感谢您的精彩回复,Benjamin!太糟糕了,显然没有办法使用另一个Promise实现而不进行替换(例如,
findAsync()
而不是
find()
)或包装(
Promise.resolve()
)我所有的Mongoose DB调用…@adrienjoly,如果这能让你感觉更好,我也在问题追踪器上问过:)如果你想帮助打开一个问题,要求他们实现拒绝挂钩(这是一个规范),也许他们会知道这对我不起作用,直到我添加了以下内容:
Mongoose.set('error',true)
。我的代码略有不同,我使用的是
Promise=require(“蓝鸟”)
mongoose=require('mongoose')
mongoose.Promise=Promise
promisifyAll(require(“mongoose”))有区别吗