diff --git a/src/http/output/BasicResponseWriter.ts b/src/http/output/BasicResponseWriter.ts index 679808c9f..6720fc0d3 100644 --- a/src/http/output/BasicResponseWriter.ts +++ b/src/http/output/BasicResponseWriter.ts @@ -36,7 +36,8 @@ export class BasicResponseWriter extends ResponseWriter { if (input.result.data) { const pipe = pipeSafely(input.result.data, input.response); pipe.on('error', (error): void => { - this.logger.error(`Writing to HttpResponse failed with message ${error.message}`); + this.logger.error(`Aborting streaming response because of server error; headers already sent.`); + this.logger.error(`Response error: ${error.message}`); }); } else { // If there is input data the response will end once the input stream ends diff --git a/src/server/BaseHttpServerFactory.ts b/src/server/BaseHttpServerFactory.ts index d840f57cd..919906e5c 100644 --- a/src/server/BaseHttpServerFactory.ts +++ b/src/server/BaseHttpServerFactory.ts @@ -64,7 +64,11 @@ export class BaseHttpServerFactory implements HttpServerFactory { async(request: IncomingMessage, response: ServerResponse): Promise => { try { this.logger.info(`Received ${request.method} request for ${request.url}`); - await this.handler.handleSafe({ request: guardStream(request), response }); + const guardedRequest = guardStream(request); + guardedRequest.on('error', (error): void => { + this.logger.error(`Request error: ${error.message}`); + }); + await this.handler.handleSafe({ request: guardedRequest, response }); } catch (error: unknown) { let errMsg: string; if (!isError(error)) { diff --git a/test/unit/server/BaseHttpServerFactory.test.ts b/test/unit/server/BaseHttpServerFactory.test.ts index 5e1894a2a..e380431cf 100644 --- a/test/unit/server/BaseHttpServerFactory.test.ts +++ b/test/unit/server/BaseHttpServerFactory.test.ts @@ -90,6 +90,15 @@ describe('A BaseHttpServerFactory', (): void => { const res = await request(server).get('/').expect(500); expect(res.text).toContain('Unknown error: apple.'); }); + + it('can handle errors on the HttpResponse.', async(): Promise => { + // This just makes sure the logging line is covered. + // Actually destroying the request to trigger an error causes issues for supertest + handler.handleSafe.mockImplementationOnce(async(input): Promise => { + input.request.emit('error', new Error('bad request')); + }); + await request(server).get('/').expect(404); + }); }); describe('with showStackTrace enabled', (): void => {