简体   繁体   中英

What's the proper way to propagate .catch in promise?

I'm using bluebird to promisify the mongoose library. So, I currently find and save data as following:

    User.findOneAsync({email: req.body.text})
      .then(function(user) {
        user.saveAsync()
          .spread(function(savedUser){
            res.json(savedUser);
          })
          .catch(function(err) {
            res.json({
              status: 500,
              message: 'foo'
            });
          });
      })
      .catch(function(err) {
         res.json({
           status: 500,
           message: 'foo'
         });
      });

Two catch functions are totally identical. This is just an demo, I sometimes have two identical catch functions in practical work. I could separate the function inside the catch into it own function. However, I had to write the catch functions multiple times anyway. What's the good approach to avoid duplicate catch functions? Any help would be appreciated.

You can actually just return user.saveAsync() . Then your error propagates to the lower catch function. Like that:

 User.findOneAsync({email: req.body.text})
  .then(function(user) {
    return user.saveAsync()
      .spread(function(savedUser){
        res.json(savedUser);
      });
  })
  .catch(function(err) {
     res.json({
       status: 500,
       message: 'foo'
     });
  });

This works because your spread returns a Promise. That promise is then passed along the outer chain, including a possible error. In the outer chain you can then catch that with your catch function which will now catch errors from the inner and outer chain since they are connected.

You could also shorten this code by much and not have two promise chains by doing something along the lines of this:

 User.findOneAsync({email: req.body.text})
 .call("saveAsync")
 .spread(function (savedUser) {
     res.json(savedUser);
 })
 .catch(function(err) {
    res.json({
      status: 500,
      message: 'foo'
    });
 });

This is generally considered good practice when working with promises.

You should avoid nesting in then success handle unless required. It makes your code more readable and you have to use just one catch function. All rejected promises gets propagated to last catch function.

User.findOneAsync({email: req.body.text})
    .then(function(user) {
        return user.saveAsync();
    })
    .spread(function(savedUser){
        return res.json(savedUser);
    })
    .catch(function(err) {
        return res.json({
            status: 500,
            message: 'foo'
        });
    });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM