首页 > 解决方案 > 是否应该将每个数据库查询都包装在 try/catch 块中

问题描述

如果我的控制器在同一个异步函数中进行多个 db 查询,每个 db 查询应该被包装在它自己的单独的 try/catch 块中,还是可以将所有 db 查询放在同一个 try/catch 中?这两种选择的理由是什么?

所有 db 查询在他们自己的 try/catch 示例中:

const confirmEmailVerification = async (req, res) => {

  const { token } = req.body;

  let user;
  try {
    const result = await db.query(
      'SELECT user_account_id FROM user_account WHERE email_verification_token = $1',
      [token]
    );

    if (result.rows.length === 0) {
      return res
        .status(400)
        .json('Please verify your account by clicking the link in your email');
    }

    user = result.rows[0].user_account_id;
  } catch (err) {
    console.error(err.message);
    return res.status(500).json('Server Error');
  }

  try {
    const active = await db.query(
      'UPDATE user_account SET email_verified = TRUE WHERE user_account_id = $1',
      [user]
    );

    return res.status(200).json({
      message: 'Email has been verified, Please login',
    });
  } catch (err) {
    console.error(err.message);
    return res.status(500).json('Server Error');
  }
};

同一个 try/catch 示例中的所有 db 查询:

const confirmEmailVerification = async (req, res) => {

  const { token } = req.body;

  let user;
  try {
    const result = await db.query(
      'SELECT user_account_id FROM user_account WHERE email_verification_token = $1',
      [token]
    );

    if (result.rows.length === 0) {
      return res
        .status(400)
        .json('Please verify your account by clicking the link in your email');
    }

    user = result.rows[0].user_account_id;

    const active = await db.query(
      'UPDATE user_account SET email_verified = TRUE WHERE user_account_id = $1',
      [user]
    );

    return res.status(200).json({
      message: 'Email has been verified, Please login',
    });
  } catch (err) {
    console.error(err.message);
    return res.status(500).json('Server Error');
  }
};

标签: node.jspostgresqlexpressnode-postgres

解决方案


这取决于这一点,如果您希望在前一个函数引发错误后继续执行函数序列。在您的情况下,它是无用的,因为在任何一个错误中,您都以res.status(500).json('Server Error'). 但有时你想继续,即使链中的某些函数抛出错误,例如:

let errors = []
try {
  f1()
} catch (e) {
  errors.push(e)
}

try {
    f2()
} catch (e) {
    errors.push(e)
}

try {
    f3()
} catch (e) {
    errors.push(e)
}

如果你把它放在一个 try/catch 块中,你会因为错误而停止f1()并且f2()根本f3()不会运行。

try {
    f1()
    f2()
    f3()
} catch (e) {
    something... 
}

推荐阅读