Как обработать ошибки в нескольких асинхронных ожиданиях, когда обещание отклонено без использования блоков try catch? - PullRequest
0 голосов
/ 29 декабря 2018

Я новичок в выражении и делаю регистрацию пользователей 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 голосов
/ 29 декабря 2018

Рекомендация по кодированию для API

1) Существует два способа аккуратной обработки ошибок.Первый - это обернуть все асинхронные маршруты блоком 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) Второй способ состоит в том, чтобы иметь промежуточное программное обеспечение, которое оборачивает все маршруты, так что перезапись try catchдля всех маршрутов избегается.Здесь синхронные и асинхронные ошибки будут обрабатываться частью .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();
});
0 голосов
/ 29 декабря 2018

Проблема в строках

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

Если либо hash, либо token throw, то вводится функция .catch, но функция catch ничего не возвращает: такпосле того, как await и catch закончатся, интерпретатор увидит что-то вроде

let [a,b] = undefined

, которое не будет работать (undefined не повторяется), поэтому весь метод .signup отклоняется,Вам нужен какой-то способ, чтобы остальная часть функции signup могла перестать выполняться, если в hash или 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 / catch, но логика может быть немного проще, так как вы можете return немедленно изнутри catch:

let a, b;
try {
  ([a, b] = await Promise.all([hash,token]));
} catch(e) {
  return res.status(400).json({status:false,msg:"error in promise"});
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...