NodeJS - 发送到客户端后无法设置 Headers

NodeJS - Cannot set Headers after they are sent to the client

所以我搜索了一下,发现要解决上述问题,我必须在发送回复后 return。但我的问题是,即使我有 return,我仍然有错误。

const dbEditCourse = (req, res, db, logger) => {
    let {
        origCourse, code, description, type
    } = req.body;
    if (!code || !description || !type) {
        res.json({
            haveEmpty: true
        });
        return;
    }
    db.transaction((trx) => {
            db.select('*').from('course_strand').where('code', '=', code)
                .then(data => {
                    if (data[0]) {

                        //error happens in this block of code
                        res.json({
                            isSuccess: false
                        });
                        return;
                        //i also tried return res.json({ isSuccess: false });

                    }
                    //wrapping this in 'else' also does not work
                    return db('course_strand')
                        .returning('*')
                        .where('code', '=', origCourse)
                        .update({ code, description, type })
                })
                .then(course => {
                    return db('activity_logs')
                        .returning('*')
                        .insert({
                            date: new Date(),
                            employee_id: req.session.emp_id,
                            module: "COURSE / STRAND",
                            activity: "EDIT"
                        })
                })
                .then(activity => {
                    if (activity[0]) {
                        res.json({
                            isSuccess: true
                        });
                        return;
                    } else {
                        res.json({
                            isSuccess: false
                        });
                        return;
                    }
                })
                .then(trx.commit)
                .catch(err => {
                    logger.error(err);
                    trx.rollback;
                    res.render('pages/error-500');
                });
        })
        .catch(err => logger.error(err));
}

module.exports = {
    dbEditCourse
}

我正在做的产生错误的是,如果记录存在,它将进入上面的代码块。除了那个特定的代码块,我没有在其他地方遇到错误。即使我有错误,代码也能正常工作。

const dbEditCourse = (req, res, db, logger) => {
    let {
        origCourse, code, description, type
    } = req.body;
    if (!(code && description && type)) {
        res.json({
            haveEmpty: true
        });
        return;
    } else { // Please Try this. 
        db.transaction((trx) => {
            db.select('*').from('course_strand').where('code', '=', code)
                .then(data => {
                    if (data[0]) {

                        //error happens in this block of code
                        res.json({
                            isSuccess: false
                        });
                        return;
                        //i also tried return res.json({ isSuccess: false });

                    }
                    //wrapping this in 'else' also does not work
                    return db('course_strand')
                        .returning('*')
                        .where('code', '=', origCourse)
                        .update({ code, description, type });
                })
                .then(course => {
                    return db('activity_logs')
                        .returning('*')
                        .insert({
                            date: new Date(),
                            employee_id: req.session.emp_id,
                            module: "COURSE / STRAND",
                            activity: "EDIT"
                        });
                })
                .then(activity => {
                    if (activity[0]) {
                        res.json({
                            isSuccess: true
                        });
                        return;
                    } else {
                        res.json({
                            isSuccess: false
                        });
                        return;
                    }
                })
                .then(trx.commit)
                .catch(err => {
                    logger.error(err);
                    trx.rollback;
                    res.render('pages/error-500');
                });
        })
        .catch(err => logger.error(err));
    }

};

module.exports = {
    dbEditCourse
};

你不能用 return 关键字打破承诺链,所有 .then 语句都会被执行(除了你在 .then 中抛出错误), res.json已被调用多次

处理 catch 块中的所有错误(包括您的错误和系统错误)。

在 catch 块中,检查错误是否由您抛出 return 响应。

const dbEditCourse = (req, res, db, logger) => {
  let {
    origCourse, code, description, type
  } = req.body;
  if (!code || !description || !type) {
    res.json({
      haveEmpty: true
    });
    return;
  }

  // util throw a error
  const breakWithMyError = () => {
    throw new Error("MY_ERROR");
  }

  db.transaction((trx) => {
    db.select('*').from('course_strand').where('code', '=', code)
      .then(data => {
        if (data[0]) {

          //error happens in this block of code
          breakWithMyError();
          //i also tried return res.json({ isSuccess: false });

        }
        //wrapping this in 'else' also does not work
        return db('course_strand')
          .returning('*')
          .where('code', '=', origCourse)
          .update({ code, description, type })
      })
      .then(course => {
        return db('activity_logs')
          .returning('*')
          .insert({
            date: new Date(),
            employee_id: req.session.emp_id,
            module: "COURSE / STRAND",
            activity: "EDIT"
          })
      })
      .then(activity => {
        // revert logic, we check for error case first
        if (!activity[0]) {
          breakWithMyError();
        }
      })
      .then(trx.commit)
      .then(() => {
        // finally you can run to here without any error
        res.json({
          isSuccess: true
        });
      })
      .catch(err => {
        // If you any error, the error comes form `breakWithMyError` or any things.
        if (err.message === "MY_ERROR") {
          // the error throw by `breakWithMyError`
          return res.json({
            isSuccess: false
          });
        }
        logger.error(err);
        trx.rollback;
        // Why you return a html page in failed case? `res.status(500).json({message: "Internal server!"});`
        res.render('pages/error-500');
      });
  })
    .catch(err => logger.error(err));
}

module.exports = {
  dbEditCourse
}