首页 > 解决方案 > Express-Mongoose 请求-响应周期/错误处理与 exp

问题描述

我的印象是 res.send() 结束了请求-响应周期,但没有return在 else 块next(ex)中调用,它将响应对象传递给错误处理中间件,导致Error: Can't set headers after they are sent.

我的理解错在哪里?我express-async-errors用来捕捉错误,如果这很重要的话。

router.get('/', async (req, res, next) => {
  // get all staff sorted by name
  const allStaff = await Staff.find().sort('name');
  if (!allStaff) {
    res.status(404).send('No staff');
  } else {
    return res.status(200).send(allStaff);
  }
  next(ex);
});

标签: node.jsexpresserror-handling

解决方案


在您的问题中,您自己提到 next() 函数将响应对象传递给错误处理中间件,因此即使您不希望下一个中间件也将执行,即 allstaff 将被成功发送,然后 next()函数将被调用。

你在做什么(没有在 else 块中返回):

发送 allstaff 对象并因此尝试结束请求响应周期,但随后调用 next() 从而调用下一个中间件,该中间件试图弄乱原本成功的请求响应周期。

router.get('/', async (req, res, next) => {
  // get all staff sorted by name
  const allStaff = await Staff.find().sort('name');
  if (!allStaff) {
    res.status(404).send('No staff');
  } else {
   res.status(200).send(allStaff);   //send the response..expect the req-res cycle to end
  }
  next(ex);     //then call next which might try to hamper the outgoing response
});

你应该怎么做:

如果您发送响应,那么它绝不会遇到其他尝试再次发送响应的语句,我个人更喜欢以下代码:

router.get('/', (req, res, next) => {
    // get all staff sorted by name
    Staff.find().sort('name').exec(function (err, docs) {     //this callback function will handle results
        if (err) {
            next();                                          //if there is an error..then the next middleware will end the req response cycle
        } else {                                             
            if (docs.length == 0) {
                res.status(404).send('No staff');           //send response,the req- res cycle ends,never disturbed again...story finished
            } else {
                res.status(200).send(docs);             //send response,the req- res cycle ends,never disturbed again.....story finished
            }
        }
    });


});

推荐阅读