I've been trying to debug my node app to find the source of an error in my log that shows up only as Error: Can't set headers after they are sent
, with no trace information or any context.
As it happens, I think I've now fixed this... I am using connect-timeout
and I was continuing processing a callback passed to an asynchronous network operation, which callback would eventually try to do a res.send()
, despite req.timedout
having been set to 'true' by connect-timeout
during the network operation.
BUT I still can't understand why my log wasn't showing trace information for this error. Anywhere that an error is returned in my code I log it to the console with:
console.log(err);
If there is trace information available in the err
object, and this seems to be placed in err.stack
, shouldn't the above statement dump the whole content of err
(including err.stack
) to the console log? My understanding is that I wouldn't be losing any information by doing the above, compared e.g. to:
console.log(err.stack);
But posts like this one seem to suggest otherwise (though the linked post has now been updated).
I actually go further, and add some relevant text to help locate the error:
console.log('error in dodgyFunction:', err);
But despite this, I was still only getting Error: Can't set headers after they are sent
, without any of the context I'd put it. Would this be because this console error message is output within an external library (like express
)? I thought that external libraries should send errors back to the main code to be dealt with accordingly?
Edit: here's an example of where I put my error and timeout checking, at the top of the callback function passed to the async operation:
var execFile = require('child_process').execFile;
execFile('dodgycommand', options, function(error, stdout, stderr) {
if (req.timedout) {
console.log('timeout detected whilst running dodgycommand, so aborting...');
return;
}
if (error) {
console.log('error running dodgycommand:', error);
res.sendStatus(400);
return;
}
// ... it's safe to continue ...
}
I basically follow this same pattern throughout.