Question

I spent a while trying to diagnose this error.

First I had created a subclass of EventEmitter

File Client.js

var bindToProcess = function(fct) {
  if (fct && process.domain) {
    return process.domain.bind(fct)
  }
  return fct
};

function Client(){
  EventEmitter.call(this);
}
util.inherits(Client, EventEmitter);

Client.prototype.success =
  function(fct) {
    this.on('success', bindToProcess(fct))
    return this;
}


Client.prototype.login = function(username, password) {
  body = {
    username : username,
    password : password
  };
  var self = this;
  request.post(url, { json:true, body: body }, function (error, response, body) {
      if (error ||response.statusCode != HTTPStatus.OK ) { 
         return self.emit('error', error);
      } 
       return self.emit('success', body);
    });
  return this;
}
module.exports = Client

Then in another file in my Express App

File user.js

var Client = require('../utils/client');
var client = new Client();

// GET '/login'
exports.login = function(req, res){
 client.login(username, password).success( function(user) {
  res.redirect('/');
   }).error( function(error) {
  res.redirect('login');
  });
}

The thing is though on the second request, the server crashes with the error:

Error: Can't set headers after they are sent.

In the interim I've solved the problem by created the Client inside the middleware rather than having it a global variable. I'm just curious why this is happening ?

Thanks, (hopefully there is enough information)

Was it helpful?

Solution

What happens here is the call of the event handling function from the first request during second request because the variable client is shared between the requests.

At first, the client is created in the global scope. Then two handlers are attached to its events and then the request is actually performed and corresponding handler is called.

On the second request, two more handlers are attached to the same object and then on either success or fail two handlers (from previous call and from the current) are notified.

So you need to move the client creation to the action method or change how the code responds on the events - I can suggest promises-like approach: pass two callbacks as parameters to one method; or just the standard callback approach: pass the error result as first argument of the callback.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top