Использование экспресс, await, catch и next для остановки выполнения функции при ошибке - PullRequest
0 голосов
/ 04 ноября 2018

Я пишу экспресс-приложение JS, используя этот стиль для маршрутизации:

router.post('/account/create', async function(req, res, next) {
    var account = await db.query(`query to see if account exists`).catch(next);
    if (account) {
        res.send('Email is unavailable.');
    } else {
        // Create account
    }
});

Если запрос возвращается успешно, но без строк, маршрут выполняется идеально. account пусто, поэтому оператор if работает, и мы создаем учетную запись.

Однако, если возникла проблема с запросом db, вызывается оператор catch, а account равен undefined, поэтому функция продолжает пытаться создать новую учетную запись, даже если была вызвана next, какие журналы выдает ошибку и 500.

Чтобы продолжить с простотой этого простого асинхронного / ожидающего простого стиля кодирования, существует ли способ легко остановить выполнение функции (или другое решение), чтобы предотвратить выполнение последующего кода без возврата к обратным вызовам?

Ответы [ 2 ]

0 голосов
/ 04 ноября 2018

Я решил использовать решение здесь , которое заключается в том, чтобы обернуть мои обработчики маршрутов в функцию, которая перехватывает ошибки для всего обработчика маршрута и вызывает next. Тогда, если мне нужно конкретно обработать ошибку, я могу использовать try-catch. Так что в 90% случаев используется обработчик ошибок next по умолчанию, в остальных 10 - просто try-catch.

Содержит все в чистоте и супер удобно, и вам никогда не придется использовать .catch() для ожидающих звонков.

0 голосов
/ 04 ноября 2018

Что-то вроде ниже должно делать работу?

Он использует try / catch в сочетании с async / await, таким образом, нет обратных вызовов.

router.post('/account/create', async function(req, res, next) {

  var account; 
  try {
      account = await db.query(`query to see if account exists`);
  } catch (e) {
    return res.status(500).send("Error checking if account exists.");
  }

  // If the account exists, return early
  if (account) {
    return res.status(500).send("Account already exists.");
  }

  // Account doesn't exist, so let's create the account!

  try {
    // Here you could create your new user account, and save it in the database, the catch would catch any DB error.

   // await db.query......

  } catch (e) {

    // Something went wrong creating the account, oops! Return.
    return res.status(500).send("Error creating account");
  }

  // The account would have been created at this point.
  return res.status(200).send("Account created!");
});

Использование обещаний, без асинхронности / ожидания.

router.post('/account/create', async function(req, res, next) {

  db.query(`query to see if account exists`)
    .then((account) => {

      // If the account exists, return early
      if (account) {
        return res.status(500).send("Account already exists.");
      }

      // Now create account
      db.query(`query to create account`)
        .then((result) => {

          // Account created fine, return.
          return res.status(200).send("Account created!");
        })
        .catch((err) => {

          // Error creating account, return.
          return res.status(500).send("Error creating account");
        });

    })
    .catch((err) => {
      return res.status(500).send("Error checking if account exists.");
    })

});
...