简体   繁体   English

如何在不使用 try catch 块的情况下处理多个 async await whle promise 中的错误?

[英]how to handle errors in multiple async await whle promise rejected without using try catch blocks?

i am new to express and was making user signup api.我是快递新手,正在制作用户注册 api。 In this i need to hash user password and generate a random string.在这我需要散列用户密码并生成一个随机字符串。 these both things are done by aync/await.If one promise got rejected then it returns the response in error handling but shows me warning for unhandled rejected promise.这两件事都是由 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})
    }
}); 
}

and promise are -和承诺是 -

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);

})
}

which is always rejected for creating error.这总是因创建错误而被拒绝。

Here is get below error这是得到以下错误

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.

how to catch these errors without using try catch or then for promises and keeping my code simple and easy to read.如何在不使用 try catch 或 then for promises 的情况下捕获这些错误并保持我的代码简单易读。

The problem is the lines问题是线条

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

If either hash or token throw, then the .catch function is entered, but the catch function doesn't return anything: so, after the await and catch have finished, the interpreter will see something like如果hashtoken抛出,则进入.catch函数,但catch函数不返回任何内容:因此,在awaitcatch完成后,解释器将看到类似

let [a,b] = undefined

which won't work ( undefined is not iterable), so the whole .signup method rejects.这将不起作用( undefined不可迭代),因此整个.signup方法拒绝。 You need some way for the rest of the signup function to know to stop executing if there was an error in hash or token , maybe something like如果hashtoken有错误,您需要某种方式让signup函数的其余部分知道停止执行,可能类似于

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;

You say you don't want to use try / catch , but the logic might be a bit easier to follow that way, since you could return immediately from inside the catch :您说您不想使用try / catch ,但遵循这种方式的逻辑可能会更容易一些,因为您可以立即从catch内部return

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

Coding Convention Suggestion for API API 编码约定建议

1) There are two ways to handle errors neatly. 1)有两种方法可以巧妙地处理错误。 The first one is by wrapping all the async routes with a try catch block which will handle both synchronous and asynchronous code errors.第一种方法是使用 try catch 块包装所有异步路由,该块将处理同步和异步代码错误。

Async/Await异步/等待

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) The second way is to have a middleware that wraps all the routes so that rewriting try catch for all the routes is avoided. 2)第二种方法是有一个中间件来包装所有路由,这样就可以避免为所有路由重写 try catch。 Here both synchronous and asynchronous errors will be handled by the .catch() part in the async Middleware.这里同步和异步错误都将由异步中间件中的 .catch() 部分处理。

Using Async Await Middleware使用异步等待中间件

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();
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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