在模块中 res.send() 之后停止 res

Stop res after res.send() in module

我正在尝试为 req.body 的验证请求创建一个模块。

我不想将以下代码添加到对服务器的每个请求中,而是将其添加到一个模块中,然后用一行代码完成。

const errors = validationResult(req);
  if (!errors.isEmpty()) {   
   return res.status(400).json({ errors: errors.array() });
  }

所以我把这段代码放在 validation.js:

const { validationResult } = require("express-validator");

// Finds the validation errors in this request and wraps them in an object with handy functions
const checkForErrors = (req, res, next) => {
  console.log("hello");
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(400).json({ errors: errors.array() });
  }
};

module.exports = checkForErrors;

app.js 中的这个:

const checkForErrors = require("../config/validation");

// get /business/biz/:id page
router.get(
  "/biz/:id",
  [param("id").isAlphanumeric().trim()],
  (req, res) => {
    checkForErrors(req,res);
    bizID = req.params.id;
    console.log(bizID);
    res.send("Hello Business biz single page ");
  }
);

但是当我这样做时出现错误,我得到 Error can't send headers after they are sent

如何确保在出现错误时响应在 validation.js 中停止? 提前致谢。

checkForErrors 已经被定义为一个中间件函数,它允许您将它放在路由处理程序的中间件链中,例如

router.get(
  "/biz/:id",
  [param("id").isAlphanumeric().trim()],
  checkForErrors,
  (req, res) => {
      bizID = req.params.id;
      console.log(bizID);
      res.send("Hello Business biz single page ");
  }
);

您唯一需要更改的是在 checkForErrors 内调用 next 以防出现错误:

//...
const errors = validationResult(req);
if (!errors.isEmpty()) {
    return res.status(400).json({ errors: errors.array() });
}
next();

编辑错误处理的更可重用的解决方案:

// create a new error class
class ValidationError extends Error {
   constructor(errors) {
      super("Validation error occurred");
      this.errors = errors;
   }
}

// throw ValidationError in case of validation errors
const checkForErrors = (req) => {
  console.log("hello");
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    throw new ValidationError(errors.array());
  }
};

// call the function inside your handler callback
router.get(
  "/biz/:id", ...  
  (req, res) => {
    checkForErrors(req);
    bizID = req.params.id;
    console.log(bizID);
    res.send("Hello Business biz single page ");
  }
);

// add a global error handling middleware and handle validation error there
app.use((err, req, res, next) => {
  if(err instanceof ValidationError) {
    return res.status(400).json({ errors: err.errors });
  }
  console.error(err.stack)
  res.status(500).send('Some unexpected error occurred!')
})