繁体   English   中英

我通过Express中间件获得了UnhandledPromiseRejection

[英]I get an UnhandledPromiseRejection with Express middleware

我试图在尝试访问addContact端点之前检查用户是否已登录。

var isLoggedIn = (req, res, next) => {
   if(req.session.user)
       next();

   //unauthorized
   res.status(401).send('Please log in.');
};

发布路由addContact看起来像这样,我正在使用isLoggedIn中间件来检查用户是否在添加之前登录。

app.post('/addContact', isLoggedIn, (req, res) => {

   //if Mongo database is not started
   if(mongoose.connection.readyState !== 1) {
       res.send(`We're sorry. We are having trouble connecting. Try again later`);
       return;
   }

   var contact = new Contact({
       _userId: req.session.user.id,
       name: req.body.name,
       phone_number: req.body.phone_number,
       email: req.body.email
   });

   console.log('adding contact from session', req.session.user);

   contact.save().then((c) => {
       res.send(`${contact.name} was added succesfully.`);
   }).catch((e) => {
       res.send(e);
   });

});

正在使用正确的会话ID req.session.user将“从会话中添加联系人:”登录到控制台。 但是,一旦尝试save()新联系人,就会出现以下错误

UnhandledPromiseRejectionWarning:未处理的承诺拒绝(拒绝ID:1):将标头发送到客户端后无法设置标头

并且正在发送的响应显示“请登录”,这在中间件isLoggedIn指定。

有人可以告诉我为什么会这样吗? 我正在尝试不重复问题,但找不到解决方案。 谢谢

您的问题在于以下代码段:

if(req.session.user)
       next();

   //unauthorized
   res.status(401).send('Please log in.');

错误: 在将标头发送到客户端后,无法设置标头本质上意味着您试图多次响应HTTP请求,而Express却不允许您这样做。 next()的调用意味着更进一步的中间件正在设置响应,然后当您调用res.status(401)您试图再次设置响应。

长话短说,您应该像这样早日返回:

var isLoggedIn = (req, res, next) => {
   if(req.session.user)
       return next(); // note we exit the middleware here!

   //unauthorized
   res.status(401).send('Please log in.');
};

致电next之后,您需要return

var isLoggedIn = (req, res, next) => {
   if(req.session.user) {
       next();
       return;
    }

   //unauthorized
   res.status(401).send('Please log in.');
};

而且实际上更好:

var isLoggedIn = (req, res, next) => {
   if (!req.session.user) {
       const err = new Error('Please login')
       err.status = 401
       throw err
    }

   next()
};

然后使用实际的错误处理程序中间件:

/**
 * Show useful information to client in development.
 */
exports.development = (err, req, res, next) => {
  err.stack = err.stack || ''
  const status = err.status || 500

  res.status(status).json({
    status,
    error
  })
}

/**
 * Do not show errors in production.
 */
exports.production = (err, req, res, next) => {
  if (err.stack) {
    delete err.stack
  }

  err.message = err.messsage || 'oops'
  err.status = err.status || 500

  res.status(err.status).json({
    status: err.status,
    error: {
      message: err.message
    }
  })
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM