如何在不使用try catch块的情况下处理多个异步等待承诺中的错误?

时间:2018-12-29 05:43:22

标签: node.js express

我是新来表达的人,正在制作用户注册api。在这种情况下,我需要对用户密码进行哈希处理并生成一个随机字符串。这两件事都是由aync / await完成的。​​如果一个诺言被拒绝,它将返回错误处理响应,但会向我显示警告,提示未处理的诺言被拒绝。

methods.signup = async (req,res,next) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
        return res.status(config.errorCodes.validation).json({errors:errors.array()});
    }
    let payload = req.body;
    var newUser = new User({
        username:payload.username,
        fullname:payload.fullname,
        email: payload.email,
        password: payload.password,
        urltoken:{
            token:null
        },
        actStatus: 0,
        provider: 'email',
       role:1
    });
    let hash = commonMethods.generatePasswordHash(payload.password);
    let token = commonMethods.createRandomString();

    let [a,b] = await Promise.all([hash,token]).catch(err=>{
        res.status(400).json({status:false,msg:"error in promise"})
     });

    newUser.password = a;
    newUser.urltoken.token = b;
    newUser.save(function(err){
        if(err) {
            return res.status(config.errorCodes.success).json({ status:false 
        ,msg:"Error in saving userdata. Please try again",err});
        }
        else {
            commonMethods.sendMail(newUser);
            return res.status(config.errorCodes.success).json({"status":true, 
        "msg":"Registered succesfully. Please Check your Email to verify 
        your account.",newUser})
    }
}); 
}

和诺言是-

commonMethods.createRandomString = function(password){
    return new Promise(function(resolve, reject) {
    var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
    var string_length = 25;
    var randomstring = '';
    for (var i=0; i<string_length; i++) {
        var rnum = Math.floor(Math.random() * chars.length);
        randomstring += chars.substring(rnum,rnum+1);
    }
   reject(randomstring);
   // resolve(randomstring);

})
}

总是会因为创建错误而被拒绝。

这里低于错误

UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
(node:15172) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

如何在不使用try catch或不作承诺的情况下捕获这些错误,并使我的代码简单易读。

2 个答案:

答案 0 :(得分:0)

问题在于线路

let [a,b] = await Promise.all([hash,token]).catch(err=>{
  res.status(400).json({status:false,msg:"error in promise"})
});

如果抛出hashtoken,则输入.catch函数,但是catch函数不返回任何内容:因此,在{{1之后}}和await完成后,解释器将看到类似

的内容
catch

无效(let [a,b] = undefined 不可迭代),因此整个undefined方法将被拒绝。您需要某种方式让.signup函数的其余部分知道如果signuphash中存在错误(可能类似

)时停止执行
token

您说您不想使用const result = await Promise.all([hash,token]).catch(err=>{ res.status(400).json({status:false,msg:"error in promise"}) }); if (!result) return; let [a,b] = result; / try,但是按照这种方式执行逻辑可能会更容易一些,因为您可以从{ {1}}:

catch

答案 1 :(得分:0)

API编码约定建议

1)有两种方法可以巧妙地处理错误。第一个是通过用try catch块包装所有异步路由,该块将处理同步和异步代码错误。

异步/等待

methods.foo = async(req, res, next) => {
try {
    // assuming bizz is a utility analogous to createRandomString
    // and returns a promise object which will either get resolved or rejected
    // if resolved the response will end in this case and end the response
    // if rejected, await will throw an error which will be caught by the catch block
    var bar = await bizz(); // Asynchronous code(which will wait for a promise to be resolved)

    // {... DO SYNCHRONOUS STUFF ...}

    // if suppose there is an error in your synchronous code,
    // then it will throw an error which also will  be caught by the catch block
    res.end();
} catch (err) {
    // {... DO WHAT YOU NEED TO WITH THE ERROR CAUGHT BY EITHER Asynchronous OR Synchronous part of the method ...}
    console.log(err);
    res.end(err);
  }
}

2)第二种方法是拥有一个包装所有路由的中间件,从而避免重写尝试捕获所有路由。在这里,同步和异步错误都将由异步中间件中的.catch()部分处理。

使用异步等待中间件

const asyncMiddleware = (asyncFunction) => {
return (req, res, next) => {
    Promise.resolve(asyncFunction(req, res, next))
    .catch((err) => {
        // DO STUFF WITH ERROR
        res.end(err);
    });
  }
};
methods.foo = asyncMiddleware((req, res, next) => {
  // assuming bizz is a utility analogous to createRandomString
  // and returns a promise object which will either get resolved or rejected
  // if resolved the response will end in this case and end the response
  // if rejected, await will throw an error which will be caught by asyncMiddleware
  var bar = await bizz(); // Asynchronous code(which will wait for a promise to be resolved)

  // {... DO SYNCHRONOUS STUFF ...}
  // if suppose there is an error in your synchronous code
  // then it will throw an error which also will be caught by asyncMiddleware
  res.end();
});