Mock a HTTP request error using Nock and Request - node.js

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

Related

How to do AJAX POST call in express.js file in handlebar?

I am trying to send/update data to mongoDB database via AAJAX call but the command is not reaching theere. I have tried debugging using alert in between the code but the command is not reaching there. Means AJAX call doesn't get executed.
Below is my AJAX POST request code:
var text = "Done";
var data = {
selectedValue: text
}
$ajax({
method: 'POST',
url: '/update-sources',
dataType: 'text/json',
data: data,
success: function(data){
console.log(data);
alert("Working!!")
}
});
And Below is the /update-sources route code:
router.post('/update-sources', function(req, res, next) {
console.log("/Update-Sources")
User.findOneAndUpdate({email: req.user.email}, {$set:{status:data.selectedValue}}, {new: true}, (err, doc) => {
if (err) {
console.log("Something wrong when updating data!");
}
else
{
res.render('taskswriter');
console.log(doc);
return "Great Working!";
}
});
});
What mistake I am doing?
Would be great if you shared browser's console output, but trying to execute attached client-side snippet, I got the following error:
VM219:7 Uncaught ReferenceError: $ajax is not defined
at <anonymous>:7:1
You've got a typo there - it should be $.ajax as you are accessing a function from within jQuery namespace (https://api.jquery.com/jQuery.ajax/)

NodeJS Request how to save Body

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.

Finding errors with request

I have a script that posts to an endpoint, like so using the node.js request module https://github.com/request/request
const options = {
url: path,
formData: {
name: name,
bundle: fs.createReadStream(path)
}
}
request.post(options, function(err, httpResponse, body) {
if (err) {
console.log('Error!')
} else {
console.log('Success!')
}
})
And I'm trying to catch when the post fails and doesn't work. I tried purposely uploading something and got a 400 response back, but it still came back with success. Is there a more appropriate way to handle error catching with the request module?
The request library doesn't populate the error argument of the request callback unless there is an actual error in the transmission or some other runtime issue. See this issue on the GitHub: 404 error does not cause callback to fail #2196.
Currently request does not handle the HTTP errors. You can wrap the
callback and add your own logic there.
To check for HTTP errors, check the statusCode property of the response argument:
request.post(options, function (err, httpResponse, body) {
if (err || httpResponse.statusCode >= 400) {
return console.error("Something went wrong");
}
console.log('Success!')
});

Node-Jasmine not failing when expected

I'm trying to setup a node-jasmine test for the first time. Currently I'm just trying to setup a simple test to see that getting the index returns status 200.
It seemed to be working but I noticed no matter what I change the status number to it never fails, for example expecting status 666, but I don't get a failure:
const request = require("request")
const helloWorld = require("../app.js")
const base_url = "http://localhost:3002/"
describe("Return the index page", function() {
describe("GET /", function() {
it("returns status code 200", function() {
request.get(base_url, function(error, response, body) {
expect(response.statusCode).toBe(666)
done()
})
})
})
})
Which returns:
Finished in 0.009 seconds
1 test, 0 assertions, 0 failures, 0 skipped
When I expected a failure here.
You need to include the done callback as a parameter to the test function.
Eg:
it("returns status code 200", function(done) {
request.get(base_url, function(error, response, body) {
expect(response.statusCode).toBe(666)
done();
})
})
Without this, the test is completing before the asynchronous request returns.
While it looks like you found your answer, I came here with a similar problem. My problem was that the request was failing, and the assertion was never reached. Once I added an error catch like below, I found my problem!
I'm new to Jasmine, but it seems odd that an exception generated inside your test wouldn't be more visible or apparent, so if anyone has feedback on how to better handle, let me know.
const request = require("request")
const helloWorld = require("../app.js")
const base_url = "http://localhost:3002/"
describe("Return the index page", function() {
describe("GET /", function() {
it("returns status code 200", function() {
request.get(base_url, function(error, response, body) {
if (error)
console.log("Something borked: ", error);
expect(response.statusCode).toBe(666)
done()
})
})
})
})

Limiting requests with the async and request modules

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.

Resources