未捕获的Promise异常

16

我知道这个问题是常见的。我正在使用es6承诺,并且有多个层次。

在运行时,当我没有捕获一个承诺时,在我的控制台上会出现未捕获的(承诺)。但事实是,我在我的代码中较低的位置确实捕获了它。

简化的快速示例:

LoginApi.js

var loginDaoCall = loginDao.login(username, password);

loginDaoCall
    .then(function (res) {
        store.dispatch(loginSuccess());
        log.log("[loginApi.login] END");
    })
    .catch(function (err) {
        store.dispatch(loginFail());
        errorUtils.dispatchErrorWithTimeout(errorLogin);
        log.log(err);
    });

return loginDaoCall;

loginContainer.js

loginApi.login(user, password).then(() => {
    // Change here instead of in render so the user can go back to login page
    this.props.history.push(baseUrlRouter + "test");
}); // <- Error here cause I don't CATCH the promise, but I do catch it in my loginapi.js

我知道如果什么都不做就会触发此错误,但是嘿,我也可以在我的API层中进行历史推送,但这不是它的职责。

有没有办法避免控制台中的错误?我甚至考虑保留它。


这是一个错误还是一个警告? - Jonas Wilms
它被显示为错误,但实际上只是一个警告,因为它并没有破坏任何东西。我讨厌在控制台看到不是由我引起的警告/错误。在我看来,这并不合理,因为这不是不良实践。 - Nevosis
1
也许你的代码是这样的? errorUtils.dispatchErrorWithTimeout(errorLogin); log.log(err); - Jonas Wilms
不过问题是,这是一个“未处理的拒绝”,如果我在我的loginContainer中捕获被拒绝的promise,我就没有错误消息。这是来自es6-promises的console.error。 - Nevosis
你的 catch 中没有抛出任何错误?那是什么错误? - Jonas Wilms
是的,有一个错误,但它特定于我的代码。当身份验证失败时,我的loginDao会拒绝某些东西(实际上是一个对象)。 编辑:未捕获的Promise(Object {code: -32001, message: "Invalid login/password"}) - Nevosis
2个回答

11

你的问题在于你正在return被拒绝的loginDaoCall,而不是已经处理错误的promise。确实,loginApi.login(user,password)返回了一个被拒绝的promise,即使在另一个分支中进行了处理,后续的.then()返回的promise也会被拒绝并且未被处理。

你可能需要做一些类似下面的操作:

// LoginApi.js
return loginDao.login(username, password).then(function (res) {
    store.dispatch(loginSuccess());
    log.log("[loginApi.login] END");
    return true;
}, function (err) {
    store.dispatch(loginFail());
    errorUtils.dispatchErrorWithTimeout(errorLogin);
    log.log(err);
    return false;
}); // never supposed to reject
// loginContainer.js
loginApi.login(user, password).then(success => {
    if (success) {
        // Change here instead of in render so the user can go back to login page
        this.props.history.push(baseUrlRouter + "test");
    }
});

实际上只返回loginDaoCall就可以了。我不太清楚有什么不同,因为它看起来是相同的实例,但可能并不是。 - Nevosis

4

听起来你在捕获块中出现了错误。当错误抛出时,没有第二个捕获块来捕获第一个捕获块中的错误。

要修复它...

.then(function (res) {
    // some code that throws an error
})
.catch(function (err) {
    // some code that throws an error
})
.catch(function (err) {
    // This will fix your error since you are now handling the error thrown by your first catch block
    console.log(err.message)
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接