27

我正在使用 bluebird Promise 库。我想链接承诺并捕获特定的承诺错误。这就是我正在做的事情:

getSession(sessionId)
  .catch(function (err) {
    next(new Error('session not found'));
  })
  .then(function (session) {
    return getUser(session.user_id);
  })
  .catch(function (err) {
    next(new Error('user not found'));
  })
  .then(function (user) {
    req.user = user;
    next();
  });

但是,如果 抛出错误getSession,则调用两个catch以及第二个then。我想在第一个停止错误传播catch,以便第二个catch仅在getUser抛出时调用,第二个thengetUser成功时调用。做什么?

4

3 回答 3

23

.catch方法返回的承诺仍然会通过回调的结果来解决,它不仅会停止链的传播。您将需要分支链:

var session = getSession(sessionId);
session.catch(function (err) { next(new Error('session not found')); });
var user = session.get("user_id").then(getUser);
user.catch(function (err) { next(new Error('user not found')); })
user.then(function (user) {
    req.user = user;
    next();
});

或使用第二个回调then

getSession(sessionId).then(function(session) {
    getUser(session.user_id).then(function (user) {
        req.user = user;
        next();
    }, function (err) {
        next(new Error('user not found'));
    });
}, function (err) {
    next(new Error('session not found'));
});

或者,更好的方法是通过链传播错误,并next仅在最后调用:

getSession(sessionId).catch(function (err) {
    throw new Error('session not found'));
}).then(function(session) {
    return getUser(session.user_id).catch(function (err) {
        throw new Error('user not found'));
    })
}).then(function (user) {
    req.user = user;
    return null;
}).then(next, next);
于 2014-07-07T20:58:43.663 回答
7

由于您将 bluebird 用于承诺,因此实际上不需要在每个函数之后使用 catch 语句。您可以将所有的 then 链接在一起,然后用一个按钮将整个事情关闭。像这样的东西:

getSession(sessionId)
  .then(function (session) {
    return getUser(session.user_id);
  })
  .then(function (user) {
    req.user = user;
    next();
  })
  .catch(function(error){
    /* potentially some code for generating an error specific message here */
    next(error);
  });

假设错误消息告诉您错误是什么,仍然可以发送特定于错误的消息,例如“找不到会话”或“找不到用户”,但您只需要查看错误消息以查看它给出的内容你。

注意:我确信无论是否有错误,您都可能有理由调用 next,但在遇到错误的情况下抛出 console.error(error) 可能很有用。或者,您可以使用其他一些错误处理函数,无论是 console.error 还是 res.send(404) 或类似的东西。

于 2014-07-07T21:07:22.250 回答
2

我是这样使用它的:

getSession(x)
.then(function (a) {
    ...
})
.then(function (b) {
    if(err){
        throw next(new Error('err msg'))
    }
    ...
})
.then(function (c) {
    ...
})
.catch(next);
于 2018-11-14T11:58:53.973 回答