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.