fix headersSent check
This issue was discovered when an over-limit request body is sent to LB4. Destroying the request socket causing the client to fail instead of receiving a meaningful error.
This commit is contained in:
parent
e7aa8353e7
commit
26e8f8f3eb
|
@ -27,13 +27,14 @@ declare namespace errorHandlerFactory {
|
|||
* @param req Incoming request
|
||||
* @param res Response
|
||||
* @param options Options for error handler settings
|
||||
* @returns false if the response has been sent before the error
|
||||
*/
|
||||
function writeErrorToResponse(
|
||||
err: Error,
|
||||
req: Express.Request,
|
||||
res: Express.Response,
|
||||
options?: ErrorWriterOptions
|
||||
): void;
|
||||
): boolean;
|
||||
|
||||
/**
|
||||
* Error-handling middleware function. Includes server-side logging
|
||||
|
|
|
@ -10,7 +10,6 @@ var SG = require('strong-globalize');
|
|||
SG.SetRootDir(path.resolve(__dirname, '..'));
|
||||
var buildResponseData = require('./data-builder');
|
||||
var debug = require('debug')('strong-error-handler');
|
||||
var format = require('util').format;
|
||||
var logToConsole = require('./logger');
|
||||
var negotiateContentProducer = require('./content-negotiation');
|
||||
|
||||
|
@ -50,9 +49,12 @@ function writeErrorToResponse(err, req, res, options) {
|
|||
|
||||
options = options || {};
|
||||
|
||||
if (res._header) {
|
||||
debug('Response was already sent, closing the underlying connection');
|
||||
return req.socket.destroy();
|
||||
// See https://nodejs.org/api/http.html#http_response_headerssent
|
||||
if (res.headersSent) {
|
||||
debug('Response was already sent. Skipping error response.');
|
||||
// We should not destroy the request socket as it causes Error: write EPIPE
|
||||
// return req.socket.destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
// this will alter the err object, to handle when res.statusCode is an error
|
||||
|
@ -67,6 +69,7 @@ function writeErrorToResponse(err, req, res, options) {
|
|||
|
||||
var sendResponse = negotiateContentProducer(req, warn, options);
|
||||
sendResponse(res, data);
|
||||
return true;
|
||||
|
||||
function warn(msg) {
|
||||
res.header('X-Warning', msg);
|
||||
|
|
|
@ -38,6 +38,24 @@ describe('strong-error-handler', function() {
|
|||
request.get('/').expect(200, 'empty', done);
|
||||
});
|
||||
|
||||
it('handles response headers already sent without destroying the request',
|
||||
function(done) {
|
||||
givenErrorHandlerForError();
|
||||
var handler = _requestHandler;
|
||||
_requestHandler = function(req, res, next) {
|
||||
res.end('empty');
|
||||
process.nextTick(function() {
|
||||
handler(req, res, next);
|
||||
});
|
||||
};
|
||||
request.post('/').send(givenLargeRequest())
|
||||
.expect(200, 'empty', function(err) {
|
||||
// Skip EPIPE
|
||||
if (err && err.code !== 'EPIPE') return done(err);
|
||||
else return done();
|
||||
});
|
||||
});
|
||||
|
||||
context('status code', function() {
|
||||
it('converts non-error "err.status" to 500', function(done) {
|
||||
givenErrorHandlerForError(new ErrorWithProps({status: 200}));
|
||||
|
@ -919,3 +937,8 @@ function getExpectedErrorData(err) {
|
|||
cloneAllProperties(data, err);
|
||||
return data;
|
||||
}
|
||||
|
||||
function givenLargeRequest() {
|
||||
const data = Buffer.alloc(2 * 1024 * 1024, 'A', 'utf-8');
|
||||
return data.toString();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue