I use request lib (https://www.npmjs.com/package/request) for a Node application.
And this simple example doesn't work :
console.log(' BEGIN ---- ');
request('http://www.google.com', function (error, response, body) {
console.log('error:', error); // Print the error if one occurred
console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
console.log('body:', body); // Print the HTML for the Google homepage.
});
console.log('END ---- ');
I only have BEGIN ---- and END ---- messages in my console, but nothing from the get request.
Did I miss something ?
Nodejs behaves asynchronously, which means when you run your script request takes some time to go and fetch data from the provided link but it will take some time to complete this task therefore other code will not wait for it to complete.
You can use callbacks to wait for the result. Below code is an easy solution for your problem.
const request = require('request')
function req(callback){
console.log(' BEGIN ---- ');
request('http://www.google.com', function (error, response, body) {
console.log('error:', error); // Print the error if one occurred
console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
console.log('body:', body); // Print the HTML for the Google homepage.
callback()
});
}
req(function(){
console.log('END ---- ');
})
But for more clean and easy to read code you must learn to use promises or async/await feature in nodejs.
Related
I am performing some http calls in an AWS lambda. The number of calls are ~400 per minute.
The calls are performed as in the following snippet
var req = http.get("https://www.google.com", res => {
let body = '';
res.on('data', chunk => {
body += chunk;
});
res.on('end', chunk => {
if (body.includes('html')) {
console.log('Got back healthy response');
} else {
console.log('Got an unexpected response');
}
})
});
req.on('error', e => {
console.log('Got an error response');
})
That is a simple https request. When the Lambda is invoked, it performs ~40 requests in a single execution.
My issue is that at the beginning, everything looks good and all the requests are performed correctly. After a while (that can be after ~30 min) calls start to degrade and I get back "socket hang up ECONNRESET" error.
I then tried using the request module and change the code with the following
const request = require('request');
request("https://www.google.com", function (error, response, body) {
if (!error && response.statusCode == 200 && body.includes('html')) {
console.log('Got back healthy response' );
} else {
console.log('Got an unexpected response');
console.log('Error: ' + error);
console.log('Response: ' + response);
console.log('Body: ' + body);
}
});
In this case, with the same number of requests within the same lambda, same setting I never get the ECONNRESET error.
I'm ok using the request module but I'm curious to know why this was happening with the default http implementation.
Is this caused by socket allocation that the request module handles in a more appropriate way?
I know similar questions have been asked already but I didn't find a good answer for my case.
This isn't really an answer but I cannot write comments.
The main difference I can see is the encoding. The default encoding in request is utf8, whereas in the http module it's buffer. Adding res.setEncoding('utf8'); might be helpful. It might not be faster. In the line body += chunk you just implicitly convert a Buffer to a string so it should be the same.
If adding the setEncoding won't change anything then you might want to report an issue to the nodejs team because it's the same as the example in http_http_get_url_options_callback. They should fix it or change the example.
So I have Problem with Request and NodeJS, is very simple but I am not an Expert.
Code:
logged: function () {
var request = require('request');
test = "nothing!";
request('http://localhost:8080/log', function (error, response, body){
console.log('error:', error);
console.log('statusCode:', response && response.statusCode);
console.log('body:', body);
test = body;
});
console.log('test', test);
Output:
Starting .../
test: nothing!
error: null
statusCode: 200
body: hi
the answer was here: How do I return the response from an asynchronous call?
Request is a asynchronous call!
the Solution is not pretty but it's work!
setTimeout(function() { console.log('test', test);}, 3000);
request is asynchronous so the console.log in the bottom will be executed before test variable is assigned with the body.
So the console.log needs to be inside the request response function.
If you want to use the body later on outside the response function, depends on how you plan to use it.
I'm using AWS Lambda to drive an Alexa Skill Kit development. In an attempt to track events, I'd like the script to send an HTTP request on launch, however from the cloud logs it appears as though the http.get function is being skipped during the execution process.
The code is shown below (google.com replaces the analytics tracking url - which has been tested in the browser);
exports.handler = function (event, context) {
var skill = new WiseGuySkill();
var http = require('http');
var url = 'http://www.google.com';
console.log('start request to ' + url)
http.get(url, function(res) {
console.log("Got response: " + res.statusCode);
// context.succeed();
}).on('error', function(e) {
console.log("Got error: " + e.message);
// context.done(null, 'FAILURE');
});
console.log('end request to ' + url);
skill.execute(event, context);
};
The context objects have been commented out to allow for 'skill.execute' to function, yet either way this HTTP request is not executing. Only the 'start' and 'end' console.logs are recorded, those internal in the function do not.
Is this a async issue? Thanks.
You need to make sure the handler is being triggered. There are two ways of accomplishing this:
You could set up a new API endpoint and execute a request on that.
You could hit the Test button and your function would be invoked with the given data.
I copied and pasted your whole snippet except for the first and the last lines (because I don't have customSkill defined anywhere). I was able to get a 200 response code.
In order to successfully complete the http request, the http.get function must be incorporated into a callback function. Else the process will not be completed and will end prematurely, using a callback allows the http request to complete (with or without an error) before continuing with the rest of the function.
WiseGuySkill.prototype.eventHandlers.onLaunch = function (launchRequest, session, response) {
// Call requestFunction to make the http.get call.
// Get response from requestFunction using requestCallback
requestFunction(function requestCallback(err) {
// If error occurs during http.get request - respond with console.log
if (err) {
console.log('HTTP Error: request not sent');
}
ContinueIntent(session,response);
});
};
The function 'requestFunction' calls http.get and fires the callback.
function requestFunction(requestCallback){
var url = "http://www.google.com";
http.get(url, function(res) {
console.log("Got response: " + res.statusCode);
requestCallback(null);
}).on('error', function (e) {
console.log("Got error: ", e);
});
}
And obviously ensure you have required 'http' at the start of the script.
Hope this helps anybody else new to this!
I have a branch in a function that isn't currently being tested. It's an error handler coming from a request operation (using the node module of the same name). Here is the particular line:
request(url, function (error, response, body) {
if (error) return cb(error);
Here is the test:
describe("handles errors", function() {
it("from the request", function (done) {
var api = nock('http://football-api.com')
.get('/api/?Action=today&APIKey=' + secrets.APIKey + '&comp_id=1204')
.reply(500);
fixture.getFixture(FixtureMock, function (err, fixture) {
expect(err).to.exist
done();
});
});
Spec fails:
Uncaught AssertionError: expected null to exist
So either sending a 500 status code as a response with no body does not cause an error in the request callback, or I'm testing the wrong thing.
Use replyWithError from doc:
nock('http://www.google.com')
.get('/cat-poems')
.replyWithError('something awful happened');
This variant of #PiotrFryga's answer worked for me, as my request callback(err, resp, body) was actually checking for the "ETIMEDOUT" error code in err:
nock('http://www.google.com')
.get('/cat-poems')
.replyWithError({code: "ETIMEDOUT"});
The only found workaround is to simulate timeout
nock('http://service.com').get('/down').delayConnection(500).reply(200)
unirest.get('http://service.com/down').timeout(100).end(function(err) {
// err = ETIMEDOUT
});
source
I'm combining the async and request modules to make api requests asynchronously and with rate limiting.
Here is my code
var requestApi = function(data){
request(data.url, function (error, response, body) {
console.log(body);
});
};
async.forEachLimit(data, 5, requestApi, function(err){
// do some error handling.
});
Data contains all the urls I make request to. Am limiting the number of concurrent request to 5 using forEachLimit method. This code makes the first 5 request then stops.
In the async docs it says "The iterator is passed a callback which must be called once it has completed". But I don't understand this, what should I be doing to signal that the request has completed?
First, you shall add callback to your iterator function:
var requestApi = function(data, next){
request(data.url, function (error, response, body) {
console.log(body);
next(error);
});
};
next(); or next(null); tells Async that all processing is done. next(error); indicates an error (if error not null).
After processing all requests Async calls its callback function with err == null:
async.forEachLimit(data, 5, requestApi, function(err){
// err contains the first error or null
if (err) throw err;
console.log('All requests processed!');
});
Async calls its callback immediately after receiving the first error or after all requests completed succesfully.