Nodejs Amazon Upload using Knox crashing at Assertion Error - node.js

I'm using the knox amazon uploader as a "proxy" to upload a sliced file from Javascript.
But the thing that've noticing is that sometimes ( sadly sometimes so I cannot identify the error exactly) when the response.statusCode isn't 200 the nodeJS crashes at an exception:
assert.js:93 throw new assert.AssertionError({
AssertionError: true == false at IncomingMessage.
(http.js:1341:9) at IncomingMessage.emit (events.js:61:17) at
HTTPParser.onMessageComplete (http.js:133:23) at Socket.ondata
(http.js:1231:22) at Socket._onReadable (net.js:683:27) at
IOWatcher.onReadable [as callback] (net.js:177:10)
Does anyone knows why this happens? Is there a way to catch that exception avoiding the server to crash?
Here's some code if it helps:
var request = client.request('PUT', '/' + params.fileName + '?partNumber=' + params.partNumber + '&uploadId=' + params.uploadId, {
'Content-Length': req.headers['content-length']
});
req.on('data', function(data){
request.write(data, 'binary');
});
request.on('response', function(response) {
if (response.statusCode== 200) {
console.log('Part '+ params.partNumber + ' inserted with etag: '+ response.headers.etag);
}
}).end();

This looks to be a bug in node.js < v0.5 where Socket.destroySoon() does not close the socket right away.
https://github.com/joyent/node/issues/1892

Related

AJAX Post request - sending json object to node.js server

I am making an Ajax Post request:
$.ajax({
type:"POST",
dataType:"json",
contentType: "application/json",
data:newWorkLog,
url:"/add",
})
.done(function(response){
console.log("Response of update: ",response)
})
.fail(function(xhr, textStatus, errorThrown){
console.log("ERROR: ",xhr.responseText)
return xhr.responseText;
});
and was expecting to pass that newWorkLog object to an API method through my node.js server:
var bodyParser = require('body-parser');
app.use(bodyParser.json())
app.post('/add', function(req, res){
console.log(req.body) //This doesnt output anything
res.send(JSON.stringify(req.body));
});
After trying some approaches, I decided to only check what is being sent to my server.
Doing this, the message I get is:
SyntaxError: Unexpected token # in JSON at position 0
at JSON.parse (<anonymous>)
at createStrictSyntaxError (C:\working\app\node_modules\body-parser\lib\types\json.js:157:10)
at parse (C:\working\app\node_modules\body-parser\lib\types\json.js:83:15)
at C:\working\app\node_modules\body-parser\lib\read.js:121:18
at invokeCallback (C:\working\app\node_modules\raw-body\index.js:224:16)
at done (C:\working\app\node_modules\raw-body\index.js:213:7)
at IncomingMessage.onEnd (C:\working\app\node_modules\raw-body\index.js:273:7)
at emitNone (events.js:106:13)
at IncomingMessage.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1055:12)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickCallback (internal/process/next_tick.js:180:9)
When I console.log my newWorkLog object, I can see from my client side, the correct json object.
when I check the param on the console I see the request payload and it looks like:
user%5Bid%5D=109&user%5BuserName%5D=myname
What could be causing that error?
You say newWorkLog is an object so you need to convert it to json to send it in your request.
$.ajax({
type:"POST",
dataType:"json",
contentType: "application/json",
data:JSON.stringify(newWorkLog),
url:"/add",
})
.done(function(response){
console.log("Response of update: ",response)
})
.fail(function(xhr, textStatus, errorThrown){
console.log("ERROR: ",xhr.responseText)
return xhr.responseText;
});

Node.js Http post request on aws lambda Socket Hang up

var http = require('http');
exports.handler = function(event, context) {
var headers = {
'content-type': 'application/x-www-form-urlencoded'
}
var options = {
host: 'stage.wings.com',
path:'/test-lambda',
form: {
'days':'3'
},
headers:headers
};
console.log(options);
var req = http.request(options, function(response) {
// Continuously update stream with data
var body = '';
response.on('data', function(d) {
body += d;
});
response.on('end', function() {
// Data reception is done, do whatever with it!
var parsed = JSON.parse(body);
console.log("success");
console.log(parsed);
});
});
// Handler for HTTP request errors.
req.on('error', function (e) {
console.error('HTTP error: ' + e.message);
completedCallback('API request completed with error(s).');
});
};
my node version : v0.10.25
If i execute on file it gives HTTP error: socket hang up
From aws lambda if i run this function it throws error
Lambda error:2016-10-09T23:11:17.200Z 89f2146f-8e75-11e6-9219-b9b32aa0a768 Error: socket hang up
at createHangUpError (_http_client.js:200:15)
at Socket.socketOnEnd (_http_client.js:285:23)
at emitNone (events.js:72:20)
at Socket.emit (events.js:166:7)
at endReadableNT (_stream_readable.js:905:12)
at nextTickCallbackWith2Args (node.js:437:9)
at process._tickDomainCallback (node.js:392:17)
There is a timeout time for aws-lambda, it will hang up after at most 300 seconds.
Here is little more about it. http://docs.aws.amazon.com/lambda/latest/dg/limits.html
you can use
context.getRemainingTimeInMillis(); which will return you remaining time of your lambda so you can flush your data. If this is intended to be run longer than five minutes, then you can implement some kind of grace-full shutdown and flush your data before that.

Twitter stream api

I am trying to learn and understand nodejs. While trying to connect to api of Twitter stream and track tweets, I get following error :
undefined:1
<html>\n<head>\n<meta http-equiv="Content-Type" content="text/html; charset=ut
^
SyntaxError: Unexpected token <
at Object.parse (native)
at IncomingMessage.<anonymous> (/home/ytsejam/public_html/nodejs/11/twitter.js:15:20)
at IncomingMessage.emit (events.js:95:17)
at IncomingMessage.<anonymous> (_stream_readable.js:764:14)
at IncomingMessage.emit (events.js:92:17)
at emitReadable_ (_stream_readable.js:426:10)
at emitReadable (_stream_readable.js:422:5)
at readableAddChunk (_stream_readable.js:165:9)
at IncomingMessage.Readable.push (_stream_readable.js:127:10)
at HTTPParser.parserOnBody [as onBody] (http.js:142:22)
here is my code which I try to connect :
var https = require("https");
var options = {
host: 'stream.twitter.com',
path: '/1.1/statuses/filter.json?track=bieber',
method: 'GET',
headers: {
"Authorization": "Basic " + new Buffer("username:password").toString("base64")
}
};
var request = https.request('https://stream.twitter.com/1.1/statuses/filter.json?track=query', function(response){
var body = '';
response.on("data", function(chunk){
var chunk = chunk.toString();
try {
var tweet = JSON.parse(chunk);
} catch (err) {
console.log("JSON parse error:" + err);
}
console.log(tweet.text);
});
response.on("end",function(){
console.log("Disconnected");
});
});
request.end();
I did a research and tried to debug. my best guess is var tweet = JSON.parse(chunk); may cause problems. second option, I am missing oauth parameters.
Can you help me ? Thanks.
Edit :
I solved this using answer here Node.js and Twitter API 1.1
JSON.parse() is throwing a SyntaxError because the data it is trying to parse is HTML and not JSON.
In general, it's a good idea to wrap JSON.parse() in a try/catch block so you can handle those sorts of things gracefully.
(It is possible that there is a problem in your oauth stuff and it is failing to authenticate. So instead of getting JSON, you are getting an HTML page telling you that authentication has failed. But that is just a guess.)

How to catch getaddrinfo ENOTFOUND

I have a list of links that I need to check before processing some data. Checking headers with http.get returns error:
events.js:72
throw er; // Unhandled 'error' event
^
Error: getaddrinfo ENOTFOUND
at errnoException (dns.js:37:11)
I cannot handle this error, and exits the process. I tried res.on("error") and try..catch on http.get but nothing works.
Below is the code snippet, and here is live example at runnable.com
//This is OK
getHeaders('http://google.com/404pag-that-does-not-exit');
//Here is the error.
//Uncoughtable error!
getHeaders('http://doesnotexistooooo.com');
function getHeaders(link){
var _http = require("http");
var myUrl = require("url");
var qs=(myUrl.parse(link).search==null) ? "" : myUrl.parse(link).search ;
var path=myUrl.parse(link).pathname;
var options = {
hostname: myUrl.parse(link).hostname,
path: path+qs,
method: 'HEAD'
};
_http.get(options, function(res) {
res.on('error',function(e){
console.log("Error: " + myUrl.parse(link).hostname + "\n" + e.message);
console.log( e.stack );
});
console.log('STATUS: ' + res.statusCode);
console.log('HEADERS: ' + JSON.stringify(res.headers));
});
}
You just need to handle the error event, as stated in the error message. According to the documentation:
If any error is encountered during the request (be that with DNS resolution, TCP level errors, or actual HTTP parse errors) an 'error' event is emitted on the returned request object.
Here is a usage example:
var getRequest = _http.get(options, function(res) {
// …
});
getRequest.on('error', function (err) {
console.log(err);
});
which yields:
$ node test.js
{ [Error: getaddrinfo ENOTFOUND] code: 'ENOTFOUND', errno: 'ENOTFOUND', syscall: 'getaddrinfo' }
At the very top level, you can do
process.on('uncaughtException', function(err) {
console.log('### BIG ONE (%s)', err);
});
if you using request npm
request
.get('http://example.com/doodle.png')
.on('response', function(response) {
console.log(response.statusCode) // 200
console.log(response.headers['content-type']) // 'image/png'
})
.on('error', function(err) { // <------- add this
console.log(err)
});

node js - I am having some trouble with JSON.parse()

I have been playing around with the youtube API and node.js, so far I have been able to get a response from the API and console.log it onto the terminal.
When I try to get the response and use JSON.parse, I get a weird error:
Got response: 200
undefined:1
http://www.w3.or
^
SyntaxError: Unexpected token u
at Object.parse (native)
at IncomingMessage.<anonymous> (/home/ubuntu/node_temp4/index.js:19:10)
at IncomingMessage.emit (events.js:88:20)
at HTTPParser.onMessageComplete (http.js:137:23)
at Socket.ondata (http.js:1137:24)
at TCP.onread (net.js:354:27)
This is my script:
var http = require("http");
var searchQuery = "cats";
var queryResponse;
var options = {
host: 'gdata.youtube.com',
path: "/feeds/api/videos?q=" + searchQuery + "&max-results=1&v=2&alt=json"
};
http.get(options, function(response) {
console.log("Got response: " + response.statusCode);
response.on('data', function(chunk){
queryResponse += chunk;
});
response.on('end', function(){
JSON.parse(queryResponse);
console.log('end');
});
}).end();
The variable queryResponse is set to undefined and you are doing queryResponse += chunk in the 'data' envent handler which means queryResponse = queryResponse + chunk so you get
undefined{"youtube":["Api", "response"]}
you can fix it by instantiating queryResponse as an empty string var queryResponse = ''

Resources