我有一个这样的路由处理程序:
router.route('/callcenter/:callcenter_id/contactgroup/:contactgroup_id')
.delete((req, res) => {
if (typeof req.body.creator === 'undefined') {
return res.status(400).json({
success: false,
error: { message: 'Invalid input' }
});
}
const ContactGroup = new ContactGroupModel(db, req.params.callcenter_id, logger);
ContactGroup.read(req.params.contactgroup_id)
.then((result) => {
if (!result) {
return res.status(404).json({
success: false,
error: { message: 'Contact group not found' }
});
}
if (req.body.creator !== result.creator) {
return res.status(400).json({
success: false,
error: { message: 'Invalid input' }
});
}
return ContactGroup.delete(req.params.contactgroup_id);
})
.then((result) => {
if (!result) {
return res.status(404).json({
success: false,
error: { message: 'Contact group not found' }
});
}
return res.json({ success: true });
})
.catch((error) => res.status(400).json({
success: false,
error: { message: error }
}));
});
read
的{{1}}和delete
函数都是承诺。我写了几个测试:
ContactGroup
所有这些都通过,但记录器在最后两个包含describe('DELETE', () => {
let id;
beforeEach(() => ContactGroup.create(data).then((result) => id = result._id));
it('Should return 200 if successful', (done) => {
chai.request(app)
.delete('/callcenter/test/contactgroup/' + id)
.send({ creator: 'user__1' })
.end((err, res) => {
expect(res.status).to.equal(200);
expect(res.body.success).to.equal(true);
return done();
});
});
it('Should return 400 if input is invalid (without creator)', (done) => {
chai.request(app)
.delete('/callcenter/test/contactgroup/' + id)
.end((err, res) => {
expect(res.status).to.equal(400);
expect(res.body.success).to.equal(false);
expect(res.body.error.message).to.equal('Invalid input');
return done();
});
});
it('Should return 400 if input is invalid (unmatched creator)', (done) => {
chai.request(app)
.delete('/callcenter/test/contactgroup/' + id)
.send({ creator: 'user__2' })
.end((err, res) => {
expect(res.status).to.equal(400);
expect(res.body.success).to.equal(false);
expect(res.body.error.message).to.equal('Invalid input');
return done();
});
});
it('Should return 404 if not found', (done) => {
ContactGroup.delete(id).then(
() => {
chai.request(app)
.delete('/callcenter/test/contactgroup/' + id)
.send({ creator: 'user__1' })
.end((err, res) => {
expect(res.status).to.equal(404);
expect(res.body.success).to.equal(false);
expect(res.body.error.message).to.equal('Contact group not found');
return done();
});
});
});
afterEach(() => ContactGroup.delete(id));
});
,UnhandledPromiseRejectionWarning: Unhandled promise rejection
我还没知道为什么调用路由处理程序中的最终Can't set headers after they are sent
块。我认为只有当promise函数被拒绝时,才会发生catch
答案 0 :(得分:1)
您的代码尝试针对同一请求发送多个响应,这就是您收到“已发送标头”的消息的原因。
你有这样的代码:
ContactGroup.read(req.params.contactgroup_id).then(...).then(...).catch(...)
并且,有一些代码路径可以最终在这两个.then()
处理程序中发送响应,从而导致该错误。在您的第一个.then()
处理程序中,您似乎认为这样做:
return res.status(404).json(...)
停止承诺链。它不是。承诺链继续并直接进入下一个.then()
处理程序。由于res.status()
没有返回任何内容,因此它将转到下一个.then()
处理程序,并将undefined
作为已解析的值。那将导致你做:
return res.status(404).json(...)
会导致有关已发送标头的消息。
我不确定你想要的确切流程,但也许你想要这样的东西,你嵌套第二个.then()
,所以当你以前做过return
时它不会执行:
router.route('/callcenter/:callcenter_id/contactgroup/:contactgroup_id').delete((req, res) => {
if (typeof req.body.creator === 'undefined') {
return res.status(400).json({
success: false,
error: {
message: 'Invalid input'
}
});
}
const ContactGroup = new ContactGroupModel(db, req.params.callcenter_id, logger);
ContactGroup.read(req.params.contactgroup_id).then((result) => {
if (!result) {
return res.status(404).json({
success: false,
error: {
message: 'Contact group not found'
}
});
}
if (req.body.creator !== result.creator) {
return res.status(400).json({
success: false,
error: {
message: 'Invalid input'
}
});
}
return ContactGroup.delete(req.params.contactgroup_id).then((result) => {
if (!result) {
return res.status(404).json({
success: false,
error: {
message: 'Contact group not found'
}
});
}
return res.json({
success: true
});
});
}).catch((error) => res.status(400).json({
success: false,
error: {
message: error
}
}));
});