Node.js 为什么这个错误会导致应用程序崩溃,而不是被捕获和处理

Node.js 为什么这个错误会导致应用程序崩溃,而不是被捕获和处理,node.js,error-handling,promise,bluebird,Node.js,Error Handling,Promise,Bluebird,我对承诺还不熟悉,现在就玩弄这些承诺。我创建了这个基本应用程序: var Promise = require("bluebird"); var express = require('express'); var bcrypt = require('bcrypt-nodejs'); var app = express(); // respond with "hello world" when a GET request is made to the homepage app.get('/',

我对承诺还不熟悉,现在就玩弄这些承诺。我创建了这个基本应用程序:

var Promise = require("bluebird");
var express = require('express');
var bcrypt = require('bcrypt-nodejs');

var app = express();

// respond with "hello world" when a GET request is made to the homepage
app.get('/', function(req, res) {


    getStuffFromDb('my_password')
        .then((hash) => {
            console.log('hash = ' + hash);
            return hash; 
        })
        .then((hash) => {
            res.send(hash);
        })
        .catch(function(error) {
            errorHandler(error, res)
        });
});


function getStuffFromDb(password) {
    return new Promise(function(resolve, reject) {
        //This should fail because it is missing a parameter, a number to specify how many loops
        bcrypt.genSalt(function(error, result) {
            if (error) {
                return reject(Error("It broke 1"));
            }
//This should cause an error as result_which_does_not_exist is not defined, and the call to the function should be bcrypt.hash(password, result_which_does_not_exist ...) so it is missing a parameter
            bcrypt.hash(result_which_does_not_exist, null, function(err, hash) { 
                if (err) {
                    return reject(Error("It broke 2"));
                } else {
                    return resolve(hash);
                }
            });
        });
    });
}


function errorHandler(error, res) {
    res.send(error.message);
}

app.listen(3000, function() {
    console.log('Example app listening on port 3000!');
});
因此,独立于此函数,应用程序应该在生成salt时失败,因为缺少一个参数。相反,它在对密码进行哈希运算时失败,因为缺少一个参数,并且我传入了一个不存在的变量。这导致我的服务器崩溃,出现以下错误:

bcrypt.hash(result_which_does_not_exist, null, function(err, hash) { ReferenceError: result_which_does_not_exist is not defined.
所以应用程序正在崩溃,但我希望这个错误得到处理,我不希望它使我的服务器崩溃。我该怎么做?我对承诺很陌生(阅读约1小时后),但据我所知,捕获应该捕捉到这一点?

首先,声明
bcrypt.genSalt
的第一个参数是可选的。所以这就是为什么它在盐的生成上没有失败

第二,承诺捕获应该正常工作。当我尝试不带蓝知更鸟的时候,它很管用。当node.js内置承诺时,为什么要使用bluebird?

首先,声明
bcrypt.genSalt
的第一个参数是可选的。所以这就是为什么它在盐的生成上没有失败


第二,承诺捕获应该正常工作。当我尝试不带蓝知更鸟的时候,它很管用。当node.js内置承诺时,为什么要使用bluebird?

bcrypt.hash
没有捕获错误并将其传递到回调,而是运行时抛出了一个引用错误,因为
result\u what\u not\u exist
是一个不存在的变量

为变量指定一个值以避免引用错误!或者将您的代码放入try/catch中

例如,这将抛出一个引用错误:

var Promise = require("bluebird");

new Promise(function(resolve, reject) {

    console.log(foo);
});

未处理的拒绝引用错误:未定义foo

这是您需要做的:

new Promise(function(resolve, reject) {

    try {
        console.log(foo);
    } catch (err) {
        reject(err);
    }
});

但这一切都没有意义–您应该修复引用错误:)

bcrypt。hash
不会捕获错误并将其传递到回调中,而是运行时抛出引用错误,因为
result\u which\u not\u exist
是一个不存在的变量

为变量指定一个值以避免引用错误!或者将您的代码放入try/catch中

例如,这将抛出一个引用错误:

var Promise = require("bluebird");

new Promise(function(resolve, reject) {

    console.log(foo);
});

未处理的拒绝引用错误:未定义foo

这是您需要做的:

new Promise(function(resolve, reject) {

    try {
        console.log(foo);
    } catch (err) {
        reject(err);
    }
});

但这都是毫无意义的——你应该修正参考错误:)

@vp_-arth抱歉,但我看不出你发布的这个重复答案在这里是如何应用的?接受答案中关于如何捕获错误的部分推荐了现在不推荐使用的域。我在使用承诺,而承诺并没有以我期望的方式捕获结果。@vp_arth我认为这个问题不应该被标记为重复?副本指定了如何捕获nodejs中的错误,我的问题是为什么这个承诺没有捕获错误。请你解释一下它们是如何重复的,因为我看不出这两个问题之间有什么关联?@vp_arth抱歉,但我看不出你发布的这个重复答案在这里有什么适用性?接受答案中关于如何捕获错误的部分推荐了现在不推荐使用的域。我在使用承诺,而承诺并没有以我期望的方式捕获结果。@vp_arth我认为这个问题不应该被标记为重复?副本指定了如何捕获nodejs中的错误,我的问题是为什么这个承诺没有捕获错误。请你解释一下它们是如何重复的,因为我认为这两个问题之间没有任何关联。啊,谢谢你提出的第一点,这是有道理的。我提供的代码不会使程序崩溃,相反,不会发生任何事情(即使应该调用catch方法并将响应发送回客户机,至少我认为这是应该发生的事情)。如果将参数密码添加到bcrypt.hash函数中(第一个参数),则会出现问题中显示的错误。我需要捕获它,以便将错误发送回客户机,否则客户机只是在等待,不知道发生了错误。啊,感谢第一点,这很有意义。我提供的代码不会使程序崩溃,相反,不会发生任何事情(即使应该调用catch方法并将响应发送回客户机,至少我认为这是应该发生的事情)。如果将参数密码添加到bcrypt.hash函数中(第一个参数),则会出现问题中显示的错误。我需要捕获它,以便将错误发送回客户端,否则客户端只是在等待,不知道发生了错误。但是,如果它不是引用错误,例如发生了其他一些意外错误(比如说bcrypt库中的一些问题),该怎么办呢。我认为try-catch不适用于异步函数。我现在尝试了类似的方法:尝试{setTimeout(function(){JSON.parse('{');},1000);}catch(e){alert(“这永远不会打印出来!”);}。因此,如果我将异步bcrcypt函数包装在try-catch语句中,它似乎永远不会执行catch。如果将try/catch代码包装为仅调用立即成功返回(异步)的函数,则它永远不会捕获错误是正确的。这是异步逻辑的解析处理程序的工作(成功、失败、错误、例外等等)要正确处理自身并最终运行回调,请在遇到错误时将其作为第一个参数处理。为了对话和您正在玩的这个项目,假设bcrypt是完美的–它将始终为您运行回调,无论是否使用
err
参数。在这个世界中,您的引用nce的错误基本上是你在打电话给bcrypt之前就绊倒了,然后想让bcrypt帮你从中恢复过来。请原谅,我根本不是异步方面的专家