Jake Jake - 5 months ago 8
Node.js Question

How do I capture a "response end" event in node.js+express?

I'd like to write an express middleware function that sets up a listener on the response's 'end' event, if one exists. The purpose is to do cleanup based on the http response code that the end handler decided to send, e.g. logging the response code and rollback/commit of a db transaction. i.e., I want this cleanup to be transparent to the end caller.

I'd like to do something like the following in express:

The route middleware

function (req, res, next) {
res.on ('end', function () {
// log the response code and handle db
if (res.statusCode < 400) { db.commit() } else { db.rollback() }
});
next();
}


The route:

app.post ("/something", function (req, res) {
db.doSomething (function () {
if (some problem) {
res.send (500);
} else {
res.send (200);
}
});
}


When I try this, the 'end' event handler never gets called. The same for
res.on('close')
, which I read about in another post. Do such events get fired?

The only other way I can think of doing this is wrapping
res.end
or
res.send
with my own version in a custom middleware. This is not ideal, because
res.end
and
res.send
don't take callbacks, so I can't just wrap them, call the original and then do my thing based on the response code that got set when they call me back (because they won't call me back).

Is there a simple way to do this?

Answer

Reading the documentation, here is the signature of res.send:

res.send(body|status[, headers|status[, status]])

Which means you can set your own status, like this: res.send( 'some string', 200 ); or even just res.send( 404 );.

This method is the one you use to send the response.

Once it is sent to the client, you can't access it anymore, so there is no callback.

This is the last thing your server does. Once it has processed the request, it sends the response.

However, you can access it before you send it to the client. Which means you can:

console.log( res );
res.send( datas );

If you want to rollback/commit, you do it when the database's callback is called, not when the response is gone.

Comments