i got this following code inside a async function. when i am calling the function i am getting stuck after the await statement. i already checked my nock address for http req mocking and it is the same as in the request.
await new Promise((resolve) => {
let req = http.request(reqUrl, function (res) {
console.info('Start http GET request');
var responseBody = '';
res.setEncoding('utf8');
// Read the response body
res.on('data', function (data) {
responseBody = data;
});
res.on('end', function () {
console.info('feature toggle response code ' + res.statusCode);
if (res.statusCode === 200) {
if (responseBody.trim() != '') {
if (responseBody === 'true') {
console.info('feature toggle is on');
self.evolveData.getByAttribute = self.evolveData.getByAttributeLimited;
} else {
console.info('feature toggle is off');
}
}
} else {
printErrorMessage('fail message', res, responseBody);
self.context.fail(responseBody);
}
resolve();
});
req.on('error', function () {
self.context.fail(responseBody);
resolve();
});
});
});
When you use http.request()
, you have to call req.end()
to actually initiate the request and send it. Note, if you switch to http.get()
, then you don't have to call req.end()
because http.get()
does it for you.
Here's a stand-alone program that demonstrates:
const http = require('http');
async function run() {
await new Promise((resolve) => {
let req = http.request("http://www.google.com", function (res) {
console.log('Start http GET request');
var responseBody = '';
res.setEncoding('utf8');
// Read the response body
res.on('data', function (data) {
responseBody += data;
});
res.on('end', function () {
console.info('feature toggle response code ' + res.statusCode);
if (res.statusCode === 200) {
console.log("got 200 response")
}
resolve();
});
});
req.on('error', function () {
console.log("error");
resolve();
});
req.end(); // <=== You were missing this
});
console.log("after await");
}
run();
If you remove the req.end()
so it's missing like it is in your code, you get the same thing. The promise never resolves because the request is never sent.
Also, for completeness, notice that the req.on('error', ...)
needs to be up at a higher level (outside the http.request()
callback) so you can get errors that might occur before the callback is called or in cases where the callback is not called because of the error.
FYI, a couple doc references:
From the doc for http.request()
:
With http.request() one must always call
req.end()
to signify the end of the request - even if there is no data being written to the request body.
From the doc for http.get()
:
The only difference between this method and
http.request()
is that it sets the method to GET and callsreq.end()
automatically.