Node.js Request module returns truncated data - javascript

I'm using request on my nodejs server to call an external JSON rest service.
This is a simplified example of my code :
var request = require("request");
request("http://www.sitepoint.com", function(error, response, body) {
var myJson = eval('(' + body+ ')');
});
It works well 90% of the time, but sometime I get this error :
Uncaught Syntax Error: Unexpected Token ILLEGAL
This error never refers to the same char into the received JSON, So in my understanding, the stream sent back by the rest service is truncated and cannot be converted to JSON.
How can I ensure myself that the request is done completly and the data complete ?

Related

Json call on unauthorized url returns Unexpected token < in JSON at position

Making ajax call:
let json = this._super(url, type, options);
On return it will return login page(HTML code) since url is unauthorized the json returned is:
SyntaxError: Unexpected token < in JSON at position 2
at JSON.parse ()
at jQuery.parseJSON (jquery.js:8520)
at ajaxConvert (jquery.js:8846)
at done (jquery.js:9264)
at XMLHttpRequest.callback (jquery.js:9718)
Errors occured: ember-metal.js:3992 TypeError: Cannot read property ‘get’ of undefined
at adapter.js:28
at tryCatcher (rsvp.js:215)
at invokeCallback (rsvp.js:393)
at publish (rsvp.js:379)
at publishRejection (rsvp.js:314)
at rsvp.js:14
ember-metal.js:3992 SyntaxError: Unexpected token < in JSON at position 2
at JSON.parse ()
at jQuery.parseJSON (jquery.js:8520)
at ajaxConvert (jquery.js:8846)
at done (jquery.js:9264)
at XMLHttpRequest.callback (jquery.js:9718)
What may be the reason?
If the resource requires authentication, then you're likely getting redirected to a login page in which case you're trying to parse the HTML code of the page as JSON.
Check the Content-Type header of the response to verify the format of the data before trying to parse it, JSON typically uses the MIME type application/json, whereas HTML uses text/html.
If server requires authentication to access the resource, then you'll typically need to set an Authorization header in your request with appropriate credentials.

Javascript API GET Request fails with code 404. Truncated server response

I am trying to fetch data via external API using google app script but I keep getting Request failed for https://api.10000ft.com returned code 404. Truncated server response:
On debugging, it tells me response not defined. What could I be doing wrong?
Here is the code:
function fetchSheet() {
var response = UrlFetchApp.fetch('https://api.10000ft.com/api/v1/users//time_entries?from=2020-01-06&to=2020-01-14&auth=token');
Logger.log(response.getContentText());
}
I've tried to send the same request from Postman, and the message I received was "invalid or missing auth token", and not 404.
It seems like you need to add header fields.
You should try something like this (and check where to get the access token from):
function fetchSheet(accessToken) {
var headers = {
headers: {
Authorization: 'Bearer ' + accessToken
}
}
var response = UrlFetchApp.fetch('https://api.10000ft.com/api/v1/users/time_entries?from=2020-01-06&to=2020-01-14&auth=token', headers);
Logger.log(response.getContentText());
}
Also, the url seems not to fulfil REST's structure: .../users/HERE_SHOULD_BE_A_USER_ID/time_entries?...
I guess that your initial mistake with the double slash was that you've missed this path param.

ExpressJS response middleware

I've made an HttpInterceptor for the front-end that send every request with some default headers and automatically encrypt body/url for every request and a middleware for the back-end that check the headers and decrypt the packet if needed.. Now I have a problem with the response middleware, because I want to send the response with encrypted body only for some requests.
app.use((req,res,next)=>{
if(req.headers['x-data-encoded'] && (req.headers['x-server'] == "HP")){
res.append('X-Encoded-Data', true);
var nsp = res.send;
res.send = function(data){
var body = Crypto.encodeData(data); // Result a string of letters and numbers
nsp.apply(this, body);
}
}
next();
});
Caught exception: TypeError: CreateListFromArrayLike called on non-object
I think that error appears because send method waits an object and it is receiving a String. If you assign manually body an object this error should dissapear or change to another one.
Besides, second parameter of apply should be an array.
Hope it helps

Why do I get "Uncaught SyntaxError" while parsing JSON string?

I am currently struggling with a JSON string that I receive from my server application.
This is the JavaScript snippet that receives the JSON string:
var connection = new WebSocket('ws://'+location.hostname+':81/', ['arduino']);
connection.onmessage = function (e) {
console.log('Received from server: ', e.data);
var response = JSON.parse(e.data);
if(response.action=="networks") {
console.log('SSID: ', response.ssid);
}
};
I get this response in my browser's console according to my console.log call above:
Received from server: {"action":"networks","ssid":"UPC6288862","rssi":-69,"enc":8}
Ending in the following error:
Uncaught SyntaxError: Unexpected token in JSON at position 60
at JSON.parse (<anonymous>)
at WebSocket.connection.onmessage (WebSocket.js:19)
connection.onmessage#WebSocket.js:19
When I manually put the string, to JSON.parse() like this:
var data = JSON.parse('{"action":"networks","ssid":"UPC Wi-Free","rssi":-42,"enc":255}');
the parsing works and I can access the fields by response.action for example.
But why I get the error? Is e.data not a proper string or do I need to add some quotes or similar to e.data before parsing?
UPDATE:
Here's a screenshot of Chrome's network tab while receiving the JSON string via the WebSocket.js:

Mocking soap services with nock

I'm working on a node app that communicates with soap services, using the foam module to parse json into a valid soap request and back again when the response is received. This all works fine when communicating with the soap services.
The issue I'm having is writing unit tests for this (integration tests work fine). I'm using nock to mock the http service and send a reply. This reply does get parsed by foam and then I can make assertions against the response.
So I cannot pass a json object as a reply because foam expects a soap response. If I try to do this I get the error:
Error: Start tag expected, '<' not found
Storing XML in javascript variables is painful and doesn't work (i.e. wrapping it in quotes and escaping inner quotes isn't valid), so I wanted to put the mocked XML response into a file and pass that as a reply.
I've tried reading the file in as a stream
return fs.createReadStream('response.xml')
...and replying with a file
.replyWithFile(201, __dirname + 'response.xml');
Both fail with an error of
TypeError: Cannot read property 'ObjectReference' of undefined
Here is the XML in the file
<env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'>
<env:Header></env:Header>
<env:Body>
<FLNewIndividualID xmlns='http://www.lagan.com/wsdl/FLTypes'>
<ObjectType>1</ObjectType>
<ObjectReference>12345678</ObjectReference>
<ObjectReference xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:nil='true'/>
<ObjectReference xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:nil='true'/>
</FLNewIndividualID>
</env:Body>
</env:Envelope>
The module being tested is
var foam = require('./foam-promise.js');
module.exports = {
createUserRequest: function(url, operation, action, message, namespace) {
var actionOp = action + '/actionRequestOp',
uri = url + '/actionRequest';
return new Promise(function(resolve, reject) {
foam.soapRequest(uri, operation, actionOp, message, namespace)
.then(function(response) {
resolve(response.FLNewIndividualID.ObjectReference[0]);
})
.catch(function(err) {
reject(err);
});
});
}
};
The assertion is using should-promised
return myRequest(url, operation, action, data, namespace)
.should.finally.be.exactly('12345678');
So it looks like the xml parser won't just accept a file (which makes sense). Does the stream not complete before it is tested?
Can an XML reply be mocked successfully with nock?
I also raised this on Github
Following pgte's advice here https://github.com/pgte/nock/issues/326 I was able to get this working by setting the correct headers, replying with an xml string (with escaped quotes).
From pgte:
It can. I don't know foam well, but I guess you have to set the
response content type header (see
https://github.com/pgte/nock#specifying-reply-headers ) so that the
client can parse the XML correctly.
Here's how the working test looks:
it('should return a user ID', function(){
var response = '<env:Envelope xmlns:env=\'http://schemas.xmlsoap.org/soap/envelope/\'><env:Header></env:Header><env:Body><UserReference>12345678</UserReference></env:Body></env:Envelope>'
nock(url)
.post('/createUserRequest')
.reply(201, response, {
'Content-Type': 'application/xml'
}
);
return createUserRequest(url, operation, action, message, options)
.should.be.fulfilledWith('12345678');
});
it('should be rejected if the request fails', function() {
nock(url)
.post('/createCaseRequest')
.replyWithError('The request failed');
return createUserRequest(url, operation, action, message, options)
.should.be.rejected;
});

Categories