我用 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.');
};
post 路由 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);
});
});
'Adding contact from session:' 正在使用正确的会话 ID req.session.user
记录到控制台。但是一旦它尝试 save()
新联系人,我就会收到以下错误
UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Cannot set headers after they are sent to the client
并且正在发送的响应显示 'Please log in',这是在中间件 isLoggedIn
.
中指定的
有人能告诉我为什么会这样吗?我尽量不重复问题,但找不到解决方案。谢谢
您遇到的问题在这段代码中:
if(req.session.user)
next();
//unauthorized
res.status(401).send('Please log in.');
错误在发送给客户端后无法设置headers本质上意味着您试图多次响应 HTTP 请求,这表示不让你做。对 next()
的调用意味着进一步向下的另一个中间件正在设置响应,然后当您调用 res.status(401)
时,您正在尝试再次设置响应。
长话短说,你应该尽早 return 像这样:
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.');
};
您需要 return
在您致电 next
之后:
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
}
})
}
我试图在尝试访问 addContact
端点之前检查用户是否已登录。
var isLoggedIn = (req, res, next) => {
if(req.session.user)
next();
//unauthorized
res.status(401).send('Please log in.');
};
post 路由 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);
});
});
'Adding contact from session:' 正在使用正确的会话 ID req.session.user
记录到控制台。但是一旦它尝试 save()
新联系人,我就会收到以下错误
UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Cannot set headers after they are sent to the client
并且正在发送的响应显示 'Please log in',这是在中间件 isLoggedIn
.
有人能告诉我为什么会这样吗?我尽量不重复问题,但找不到解决方案。谢谢
您遇到的问题在这段代码中:
if(req.session.user)
next();
//unauthorized
res.status(401).send('Please log in.');
错误在发送给客户端后无法设置headers本质上意味着您试图多次响应 HTTP 请求,这表示不让你做。对 next()
的调用意味着进一步向下的另一个中间件正在设置响应,然后当您调用 res.status(401)
时,您正在尝试再次设置响应。
长话短说,你应该尽早 return 像这样:
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.');
};
您需要 return
在您致电 next
之后:
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
}
})
}