From a8ab8056939bc37b6849a39728c811013f85e1a3 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Fri, 14 Feb 2020 22:25:57 +0100 Subject: [PATCH] src: inform callback scopes about exceptions in HTTP parser Refs: https://github.com/nodejs/node/commit/4aca277f16b8649b5fc21d41f340fad0a47c2e61 Refs: https://github.com/nodejs/node/pull/30236 Fixes: https://github.com/nodejs/node/issues/31796 --- src/node_http_parser.cc | 2 ++ ...est-http-uncaught-from-request-callback.js | 29 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 test/parallel/test-http-uncaught-from-request-callback.js diff --git a/src/node_http_parser.cc b/src/node_http_parser.cc index a8c48999c57901..40ece82b625746 100644 --- a/src/node_http_parser.cc +++ b/src/node_http_parser.cc @@ -330,6 +330,7 @@ class Parser : public AsyncWrap, public StreamListener { this, InternalCallbackScope::kSkipTaskQueues); head_response = cb.As()->Call( env()->context(), object(), arraysize(argv), argv); + if (head_response.IsEmpty()) callback_scope.MarkAsFailed(); } int64_t val; @@ -401,6 +402,7 @@ class Parser : public AsyncWrap, public StreamListener { InternalCallbackScope callback_scope( this, InternalCallbackScope::kSkipTaskQueues); r = cb.As()->Call(env()->context(), object(), 0, nullptr); + if (r.IsEmpty()) callback_scope.MarkAsFailed(); } if (r.IsEmpty()) { diff --git a/test/parallel/test-http-uncaught-from-request-callback.js b/test/parallel/test-http-uncaught-from-request-callback.js new file mode 100644 index 00000000000000..5c75958617898f --- /dev/null +++ b/test/parallel/test-http-uncaught-from-request-callback.js @@ -0,0 +1,29 @@ +'use strict'; +const common = require('../common'); +const asyncHooks = require('async_hooks'); +const http = require('http'); + +// Regression test for https://github.com/nodejs/node/issues/31796 + +asyncHooks.createHook({ + after: () => {} +}).enable(); + + +process.once('uncaughtException', common.mustCall(() => { + server.close(); +})); + +const server = http.createServer(common.mustCall((request, response) => { + response.writeHead(200, { 'Content-Type': 'text/plain' }); + response.end(); +})); + +server.listen(0, common.mustCall(() => { + http.get({ + host: 'localhost', + port: server.address().port + }, common.mustCall(() => { + throw new Error('whoah'); + })); +}));