javascript - Warning - Unhandled promise rejection: Can't set headers after they are sent -


i have route handler this:

router.route('/sipprovider/:sipprovider_id/phonelist')         .post((req, res) => {             const body = req.body;             if (typeof body.phones === 'undefined') {                 return res.status(400).json({                     success: false,                     error: { message: 'invalid input' }                 });             }             if (!array.isarray(body.phones) || body.phones.length === 0) {                 return res.status(400).json({                     success: false,                     error: { message: 'invalid input' }                 });             }             let = body.phones.indexof('');             while (i >= 0) {                 body.phones.splice(i, 1);                 = body.phones.indexof('');             }             body.phones.map((phone) => {                 if (typeof phone !== 'string') {                     return res.status(400).json({                         success: false,                         error: { message: 'invalid input' }                     });                 }             });             const sipprovider = new sipprovidermodel(db, logger);             sipprovider.pushphonelist(req.params.sipprovider_id, body.phones)                 .then((result) => {                     if (result) {                         return res.json({ success: true });                     }                     return res.status(404).json({                         success: false,                         error: { message: 'sip provider not found' }                     });                 })                 .catch((error) => res.status(400).json({                     success: false,                     error: { message: error }                 }));         }); 

pushphonelist function of sipprovider promise. , write several tests:

describe('post', () => {             let id;             beforeeach(() => sipprovider.create(data).then((result) => id = result._id));             it('should return 200 if successful', (done) => {                 chai.request(app)                     .post('/sipprovider/' + id + '/phonelist')                     .set('authorization', token)                     .send({ phones: ['02873000050'] })                     .end((err, res) => {                         expect(res.status).to.equal(200);                         expect(res.body.success).to.equal(true);                         return done();                     });             });             it('should return 200 if successful', (done) => {                 chai.request(app)                     .post('/sipprovider/' + id + '/phonelist')                     .set('authorization', token)                     .send({ phones: ['02873000050', ''] })                     .end((err, res) => {                         expect(res.status).to.equal(200);                         expect(res.body.success).to.equal(true);                         return done();                     });             });             it('should return 400 if input invalid (undefined phones)', (done) => {                 chai.request(app)                     .post('/sipprovider/' + id + '/phonelist')                     .set('authorization', token)                     .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 invalid (not array)', (done) => {                 chai.request(app)                     .post('/sipprovider/' + id + '/phonelist')                     .set('authorization', token)                     .send({ phones: '02873000050' })                     .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 invalid (empty list)', (done) => {                 chai.request(app)                     .post('/sipprovider/' + id + '/phonelist')                     .set('authorization', token)                     .send({ phones: [] })                     .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 invalid (not array of string)', (done) => {                 chai.request(app)                     .post('/sipprovider/' + id + '/phonelist')                     .set('authorization', token)                     .send({ phones: ['02873000050', {}] })                     .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) => {                 sipprovider.delete(id).then(                     () => {                         chai.request(app)                             .post('/sipprovider/' + id + '/phonelist')                             .set('authorization', token)                             .send({ phones: ['02873000050'] })                             .end((err, res) => {                                 expect(res.status).to.equal(404);                                 expect(res.body.success).to.equal(false);                                 expect(res.body.error.message).to.equal('sip provider not found');                                 return done();                             });                     });             });             aftereach(() => sipprovider.delete(id));         }); 

all of them pass, logger records warnings in last test containing unhandledpromiserejectionwarning: unhandled promise rejection, can't set headers after sent

i haven't got why ultimate catch block in route handler gets called. thought when promise function gets rejected, catch occur

first off, in code:

        body.phones.map((phone) => {             if (typeof phone !== 'string') {                 return res.status(400).json({                     success: false,                     error: { message: 'invalid input' }                 });             }         }); 

you can end calling res.status() multiple times. can cause "can't set headers after sent" problem. problem here return returns .map() callback. doesn't stop other callbacks in .map() , doesn't prevent rest of code after block executing cause response sent.

you fix issue doing this:

if (!body.phones.every(phone => typeof phone === 'string')) {      return res.status(400).json({          success: false,          error: { message: 'invalid input' }      }); } 

this run through body.phones items, test see if correct type , then, outside loop, if not correct type, return. send 1 response , return outer function, stopping further execution.


Comments

Popular posts from this blog

php - Vagrant up error - Uncaught Reflection Exception: Class DOMDocument does not exist -

vue.js - Create hooks for automated testing -

Add new key value to json node in java -