Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 未处理的拒绝承诺:Can';t在发送邮件后设置邮件头_Javascript_Node.js_Unit Testing_Header_Promise - Fatal编程技术网

Javascript 未处理的拒绝承诺:Can';t在发送邮件后设置邮件头

Javascript 未处理的拒绝承诺:Can';t在发送邮件后设置邮件头,javascript,node.js,unit-testing,header,promise,Javascript,Node.js,Unit Testing,Header,Promise,我有一个这样的路由处理程序: router.route('/callcenter/:callcenter_id/contactgroup/:contactgroup_id') .delete((req, res) => { if (typeof req.body.creator === 'undefined') { return res.status(400).json({ success: false,

我有一个这样的路由处理程序:

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 }
            }));
    });
ContactGroup.read(req.params.contactgroup_id).then(...).then(...).catch(...)
ContactGroup
read
delete
功能都是承诺。我写了几个测试:

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));
        });
它们都通过了,但记录器在最后两个测试中记录了一些警告,其中包含
未处理的PromisejectionWarning:Unhandled promise rejection
发送后无法设置标头


我不知道为什么路由处理程序中的最终
catch
块会被调用。我认为只有当promise函数被拒绝时,
catch
才会出现

您的代码尝试为同一请求发送多个响应,这就是为什么您会收到关于“headers havey sent”的消息

您有如下代码:

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 }
            }));
    });
ContactGroup.read(req.params.contactgroup_id).then(...).then(...).catch(...)
还有一些代码路径,您可以在这些
.then()
处理程序中发送响应,从而导致错误。在第一个
.then()
处理程序中,您似乎认为:

return res.status(404).json(...)
停止承诺链。事实并非如此。承诺链将继续并直接进入下一个
.then()
处理程序。由于
res.status()
不返回任何内容,因此它将转到下一个
.then()
处理程序,并将
未定义的
作为解析值。这将导致您执行以下操作:

return res.status(404).json(...)
这会导致有关标头的消息已被发送


我不确定您想要的确切流,但可能您想要这样的东西,在这里嵌套第二个
。然后()
,这样在您之前执行
返回时它就不会执行了:

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
        }
    }));
});

在catch block中的
res.json()之前添加
return
,非常感谢。这正是我想要的行为