Can't remove headers after they are sent

独自空忆成欢 提交于 2019-12-10 23:37:02

问题


I am getting inconsistent results from my server. Sometimes the right response is sent and sometimes I get the error

Can't remove headers after they are sent

Using Node.js, Koa.js, and Mongoose

router
.get('/events/', function* getEvent() {
  let eventList = [];
  yield Event.find({}, (error, events) => {
    if (error) {
      this.response.body = 'Unable to get events.';
      this.status = 404;
      return;
    }

    eventList = events;
    eventList.sort((first, second) => {
      // sort implementation
    });

    this.response.body = eventList;
    this.status = 200;
  });
});

回答1:


The issue is caused by your callback which introduces a race condition since your yield isn't waiting for it to finish. In Koa v1.x, you generally only use a callback API to return a promise.

Here's how you'd write your example with Koa v1.x:

router
  .get('/events', function * () {
    let events
    try {
      events = yield Event.find({})
    } catch (err) {
      this.status = 503
      this.body = 'Unable to get events'
      return
    }
    events = sort(events)
    this.body = events  // Implicit 200 response
  })

Event.find just needs to return something yieldable like a promise. Check to see if the library your using has a promise-returning version.

Though normally you'd just write it like this:

router
  .get('/events', function * () {
    let events = yield Event.find({})
    events = sort(events)
    this.body = events
  })

Since it's an internal error (500 response) if Event.find is down. Koa will turn uncaught errors into 500 responses.




回答2:


Basically, after you set this.status to 200, it throws an error because this.response.body is probably undefined. Go ahead and console.log() this.response.body and see if it is defined. If it is undefined, I would guess req.body is not being populated correctly OR it is an asynchronous node problem. Basically, eventList.sort() is asynchronously executing as this.response.body = eventList is set. Thus eventList is not sorted yet when you set it. To fix this put it inside eventList.sort() callback.

EDIT: after seeing your comment, I am pretty sure it is asynchronous problem now. Let me know if putting the last two lines inside the sort call works out for you.



来源:https://stackoverflow.com/questions/38450258/cant-remove-headers-after-they-are-sent

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!