brianc/node-domain-middleware

What should happen when the request completes *before* the domain catches an exception?

Opened this issue · 0 comments

This module is awesome, thanks so much for making it!

I just ran into an odd issue, and I'm honestly not sure where (in what layer) it's best to fix it. I'm curious what you think.

Basically, sometimes you can have an async action that starts during the processing of a request, but the request doesn't actually wait for the async action to complete before it sends a response back to the client. (An example of this is an endpoint that logs metrics to an external service, like librato or statsd, or sends an email as a byproduct of something, like user account registration.)

If an error happens in one of these async actions, but the response has already been sent, then right now the error isn't properly handled. (This middeware still catches it, because the error is in the domain, and it calls next(). In the version of connect that I'm using (very old, I know), the error is then just logged to stdout and silently ignored, which is totally not what I ever want.

How would you react if it first checked to see if the response has already been sent before it calls next() with the error? (And otherwise, re-throwing the error for process.on('uncaughtException' to catch?)

Here is an example of the failure case:

app = express();
app.use(require('express-domain-middleware'));
app.put('/user', function(req, res, next) {
  setTimeout(sendEmail.bind(null, req.params.emailAddress), 1000);
  res.send(200, {username: 'charles'});
});

function sendEmail(emailAddress) {
  throw new Error('This is a bug!');
};

Now, requesting the /user will immediately return 200, then a second will pass, then we will see This is a bug! in the console and nothing else will happen.