Express 使用Mongoose预保存钩子导致:错误[ERR\u HTTP\u HEADERS\u SENT]:发送到客户端后无法设置头

Express 使用Mongoose预保存钩子导致:错误[ERR\u HTTP\u HEADERS\u SENT]:发送到客户端后无法设置头,express,mongoose,mongoose-schema,Express,Mongoose,Mongoose Schema,我试图在Mongoose中挂接save函数,以便在模式中不满足特定条件时向RESTAPI的客户端返回错误。我不能为此使用验证器,因为限制是在模式的多个字段上计算的 我正在尝试添加以下样式的挂钩: mySchema.pre('save', function (next) { if(condition_is_not_met) { const err = new Error('Condition was not met'); next(err); } next(); });

我试图在Mongoose中挂接save函数,以便在模式中不满足特定条件时向RESTAPI的客户端返回错误。我不能为此使用验证器,因为限制是在模式的多个字段上计算的

我正在尝试添加以下样式的挂钩:

mySchema.pre('save', function (next) {
  if(condition_is_not_met) {
    const err = new Error('Condition was not met');
    next(err);
  }
  next();
});
当我尝试调用试图插入违反钩子中检查条件的对象的端点时,这会引发错误:

错误[ERR\u HTTP\u HEADERS\u SENT]:发送后无法设置头 给客户

我猜这是因为在写入头并将其发送到客户端的路由上继续执行

router.post('/mySchema', returnType, (req, res) => {
  const s = new mySchema(req.body);
  s.save((err) => {
    if (err) {
      const msg = { message: 'Could not add', error: err }; // This is returned to the caller
      res.status(500);
      res.send(msg);
    }
    res.status(200);
    res.send(s);
  });
});

如何解决此问题?我已经搜索了很多,但是到目前为止我找到的主题并不能帮助我解决问题。他们只帮助我确定原因,而没有提供有效的解决方案。

您是否尝试使用其他分支来获得成功响应?因为即使对象无效,仍然会执行成功响应。试试下面的方法

router.post("/mySchema", returnType, (req, res) => {
  const s = new mySchema(req.body);
  s.save(err => {
    if (err) {
      const msg = { message: "Could not add", error: err };
      res.status(500);
      res.send(msg);
    } else {
      res.status(200);
      res.send(s);
    }
  });
});

请原谅我的代码格式设置,我是AFK

您是否尝试为状态200设置一个else分支?我的意思是,即使您发送的对象无效,执行仍将到达成功响应,因此响应2次。@Teebo刚刚尝试了,但也无法解决问题。如果我省略了钩子,实际上不会抛出错误。只需添加钩子,就会引入错误。这一定与某些东西失去同步有关,但我不能确定到底是什么。@Teebo我不正确,解决了这个问题。我在重写钩子中的错误集时被抛出。需要解决这一问题,以确保问题的解决方案有效。如果您在将来为面临相同问题的其他人发布您的解决方案,我可以在找到如何防止覆盖钩子设置的错误后将其标记为解决方案;返回res.send(msg);你被赦免了。这样做解决了问题,但需要将错误设置更改为:const msg={message:(err.message)?err.message:'无法添加',错误:err};不用担心,我会的。我们也可以这样使用一行:res.status(500).send(msg);缩短代码。@Ruud,我很高兴它为解决这个问题提供了一些线索@SuleymanSah我知道我可以链接这些方法,但我需要确保其他方法在将来可以很容易地跟随执行。将每个操作分离到它自己的行中会使代码对某些人更具可读性。我很好奇,错误仍然会在节点控制台中抛出500状态,但有了它,我可以将400状态返回给客户端,这是相当正确的还是有其他方法可以做到这一点?