Object #<IncomingMessage> has no method 'serverError' - mysql

I am using node.js: sailsjs on ubuntu
node version: 0.10.37
sails version: 0.11.0
npm version: 1.4.28
ubuntu version: 14.04.2
I am trying to log the value returned by GCM push notification service into a mysql table. The part of push notification service (PushNotifications.js file) with which I am logging into the db table, is shown below:
var req = https.request(options, function(res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('Response from GCM: ' + chunk);
GcmLog.add(recipients, chunk, function(err, response){
if(err){
res.serverError(err);
}else{
res.json({msg: 'yes'});
}
});
});
});
The GcmLog.js model has the following function to push the data into the db table:
add: function(device_id, chunk, callback){
GcmLog.create({user: device_id, log: chunk}).exec(function(err, response){
if(err){
return callback(err, null);
}else{
callback(null, response);
}
});
}
When I send a push notification, the message is delivered successfully and displayed on the android device, but nothing gets logged into the db table. I am getting the following error in the log file of the app:
/path/to/node_modules/sails-mysql/node_modules/mysql/lib/protocol/Parser.js:82
throw err;
^
TypeError: Object #<IncomingMessage> has no method 'serverError'
at /path/to/api/services/PushNotifications.js:44:13
at /path/to/api/models/GcmLog.js:29:12
at bound (/path/to/node_modules/sails/node_modules/lodash/dist/lodash.js:957:21)
at applyInOriginalCtx (/path/to/node_modules/sails/node_modules/waterline/lib/waterline/utils/normalize.js:416:80)
at wrappedCallback (/path/to/node_modules/sails/node_modules/waterline/lib/waterline/utils/normalize.js:326:16)
at _normalizeCallback.callback.error (/path/to/node_modules/sails/node_modules/waterline/node_modules/switchback/lib/normalize.js:42:31)
at _switch (/path/to/node_modules/sails/node_modules/waterline/node_modules/switchback/lib/factory.js:46:28)
at /path/to/node_modules/sails/node_modules/waterline/lib/waterline/query/dql/create.js:216:14
at bound (/path/to/node_modules/sails/node_modules/lodash/dist/lodash.js:957:21)
at applyInOriginalCtx (/path/to/node_modules/sails/node_modules/waterline/lib/waterline/utils/normalize.js:416:80)
at wrappedCallback (/path/to/node_modules/sails/node_modules/waterline/lib/waterline/utils/normalize.js:326:16)
at _normalizeCallback.callback.error (/path/to/node_modules/sails/node_modules/waterline/node_modules/switchback/lib/normalize.js:42:31)
at _switch (/path/to/node_modules/sails/node_modules/waterline/node_modules/switchback/lib/factory.js:46:28)
at afterwards (/path/to/node_modules/sails/node_modules/waterline/lib/waterline/adapter/dql.js:88:16)
at bound (/path/to/node_modules/sails/node_modules/lodash/dist/lodash.js:957:21)
at applyInOriginalCtx (/path/to/node_modules/sails/node_modules/waterline/lib/waterline/utils/normalize.js:416:80)
error: Forever detected script exited with code: 8
And then the server crashes and restarts after several attempts. I am unable to trace out the reason for this. Any help in explanation of what is happening and how to overcome this, will be appreciated.

Related

Testing an AWS Lambda function

I need to create a lambda function to act as the middleman between a mobile Java app and an AWS RDS MySQL database. The idea is to submit queries from the mobile app and then send them off to the lambda function, which will then return the query. I have a basic MySQL query set up in my AWS lambda:
var mysql = require('mysql');
var config = require('./config.json');
var pool = mysql.createPool({
host : config.dbhost,
user : config.dbuser,
password : config.dbpassword,
database : config.dbname
});
exports.handler = (event, context, callback) -> {
context.callbackWaitsForEmptyEventLoop = false;
pool.getConnection(function(err, connection) {
if (err) throw err; // not connected!
// Use the connection
connection.query('select Album from record', function (error, results, fields) {
// When done with the connection, release it.
connection.release();
// Handle error after the release.
if (error) callback(error);
else callback(null, results[0].Album);
// Don't use the connection here, it has been returned to the pool.
});
});
};
And all that I am currently trying to do is get this code to run and output what the query will return. I've seen tutorials where people seem to just click test and have the code run, but it keeps asking me to create a test, and I'm not sure what exactly I would need to do to test this function.
EDIT: I realized I was missing a small change in my lambda uploaded code, but I am now getting an error on line 10 saying there is an unexpected token >.
I'm not sure what's wrong here, as the tutorial I watched seems to have the same exact thing.
Since you're not passing in any parameters through the context, you can just create a test with the defaults or an empty object {}, and click Test in the console. It will invoke your Lambda function as if it had been called from your mobile app, and you can debug from there.

JSON file input error on fs module of nodejs websocket script

I have a json file which is updated every 30 seconds by an application on the server. I have written a small server script for nodejs to provide this json file over websocket (socket.io) as given below.
var app = require('http').createServer();
var io = require('socket.io')(app);
var fs = require('fs');
app.listen(8081, '127.0.0.1');
io.on('connection', function(socket) {
fs.readFile('/tmp/live-info', 'utf8', function (err, data) {
if (err) throw err;
firstDataObj = JSON.parse(data);
socket.emit('alert', firstDataObj );
});
});
var prObj;
setInterval(function(){
fs.readFile('/tmp/live-info', 'utf8', function (err, data) {
if (err) throw err;
data = JSON.parse(data);
scTime = data.schedulerTime;
delete data.schedulerTime;
if (JSON.stringify(prObj) !== JSON.stringify(data)) {
prObj = data;
console.log(prObj.current.name, io.engine.clientsCount);
prObj.schedulerTime = scTime;
io.emit('alert', prObj );
delete prObj.schedulerTime;
} else {
console.log("No change", prObj.current.name, "Total connections: ", io.engine.clientsCount);
}
});
}, 21100);
As you can see, the script periodically checks for changes to the json file and will emit the parsed object if changes in contents (except the timestamp) are detected.
I am managing nodejs process on the server using pm2. Everything works fine but I am repeatedly getting the follow error on the logs
SyntaxError: Unexpected end of JSON input
at Object.parse (native)
at /var/www/scheduleio/server.js:15:25
at tryToString (fs.js:449:3)
at FSReqWrap.readFileAfterClose [as oncomplete] (fs.js:436:12)
There are no noticeable breaks found on the client as well. However, I would like to understand how to fix this error as I am getting around 200 of them on the logs each day and if the script can be enhanced in any way (as this is my first such script).
My guess is the error comes when the file is being written by the other application while your nodejs script is checking it therefore parsing the JSON while it's not completely written.
The error unexpected end of JSON input means the JSON is malformed.

Lambda AWS not calling node mysql callbacks

I am trying to process bounces sent from Amazon's Simple Email Service via their Simple Notification Service vi a Lambda on AWS.
I'm running the following script:
var aws = require('aws-sdk');
var mysql = require('mysql');
Processor = {};
Processor.initializeConnection = function() {
console.log('Connecting to database');
Processor.connection = mysql.createConnection({
host : 'MYHOST',
user : 'MYUSER',
password : 'PASSWORD',
database : 'DATABASE'
});
console.log('Connection configured');
Processor.connection.connect(function(err) {
console.log('****');
console.log(err);
if (err != null) {
console.log('Could not connect to database');
return false;
} else {
console.log('Successfully connected to database');
return true;
}
});
console.log('Should not get here');
};
exports.handler = function(event,context){
console.log('Received event:');
var message = event.Records[0].Sns.Message;
// Get the object from the event and show its content type
if(Processor.initializeConnection()) {
context.fail('Database connection failed');
return;
}
context.succeed(message);
};
I upload this script as index.js along with node_modules containing the node mysql module all as a zip file.
I get the following output from Amazon when this is run:
START RequestId: 378b8a8c-30d4-11e5-9db4-9b9537e3f53d
2015-07-23T00:46:13.159Z 378b8a8c-30d4-11e5-9db4-9b9537e3f53d Received event:
2015-07-23T00:46:13.160Z 378b8a8c-30d4-11e5-9db4-9b9537e3f53d Connecting to database
2015-07-23T00:46:14.035Z 378b8a8c-30d4-11e5-9db4-9b9537e3f53d Connection configured
2015-07-23T00:46:14.095Z 378b8a8c-30d4-11e5-9db4-9b9537e3f53d Should not get here
END RequestId: 378b8a8c-30d4-11e5-9db4-9b9537e3f53d
REPORT RequestId: 378b8a8c-30d4-11e5-9db4-9b9537e3f53d Duration: 937.51 ms Billed Duration: 1000 ms Memory Size: 128 MB Max Memory Used: 14 MB
None of the code inside the connect fallback is run. I'm expecting it to report a connection failure as I'm not using valid credentials.
If I run a version of the code locally under nodejs the connect callback does fire. It just doesn't fire under Lambda.
Due to the asynchronous nature of node.js, your code might be exiting as a result of context.succeed() before all of your functions are executed.
See:
Async AWS Lambda not executed if caller returns too early
Why is this HTTP request not working on AWS Lambda?

Insert data into mysql with node.js works, but script hangs

I've got this script for reading a file and then insert the data into mysql tables. The script works, but it hangs, so I have to press CTRL-C to stop the script.
But the script should stop normally, what do I have to change?
var fs = require('fs');
var filename;
var myGID;
filename = "data/insertUser1_next.json";
function get_line(filename, line_no, callback) {
fs.readFile(filename, function (err, data) {
if (err) throw err;
// Data is a buffer that we need to convert to a string
// Improvement: loop over the buffer and stop when the line is reached
var lines = data.toString('utf-8').split("\n");
if(+line_no > lines.length){
return callback('File end reached without finding line', null);
}
// lines
callback(null, lines[0], lines[1], lines[2], lines[3]);
});
}
get_line(filename, 0, function(err, line, line2, line3, line4){
line = line.replace(/(\r\n|\n|\r)/gm,"");
line2 = line2.replace(/(\r\n|\n|\r)/gm,"");
line3 = line3.replace(/(\r\n|\n|\r)/gm,"");
/*line4 = line4.replace(/(\r\n|\n|\r)/gm,"");*/
console.log('The line: ' + line);
console.log('The line2: ' + line2);
console.log('The line3: ' + line3);
console.log('The line4: ' + line4);
var post = {gid: line, uid: line2};
var post2 = {uid: line2, displayname: line3, password: line4};
var mysql = require('mysql');
var db_config = {
host : '123.456.789.012',
user : 'user',
password : 'password',
database : 'maindata'
};
var con = mysql.createPool(db_config);
con.getConnection(function(err){
if (err) {
console.log(err);
return;
}
con.query('INSERT INTO group_user SET ?', post, function(err, result) {
if (err) {
console.log(err);
return;
}
});
con.query('INSERT INTO users SET ?', post2, function(err, result) {
if (err) {
console.log(err);
return;
}
});
});
});
Here you can see what happened:
When you are done using the pool, you have to end all the connections or the Node.js event loop will stay active until the connections are closed by the MySQL server. This is typically done if the pool is used in a script or when trying to gracefully shutdown a server. To end all the connections in the pool, use the end method on the pool:
pool.end(function (err) {
// all connections in the pool have ended
});
So, if you place con.end() after your queries are done, the script will terminate normally
The following statement will close the connection ensuring that all the queries in the queue are processed. Please note that this is having a callback function.
connection.end(function(err){
// Do something after the connection is gracefully terminated.
});
The following statement will terminate the assigned socket and close the connection immediately. Also there is no more callbacks or events triggered for the connection.
connection.destroy();
hey I suggest to install forever and start node servers.js with forever you dont need any terminal open.
And you need to close you mysql connection at the end to stop you hangs problem, i think.
npm install -g forever
npm install forever
//FOR your Problem
con.end(function(err){
// Do something after the connection is gracefully terminated.
});
con.destroy();
The following statement will close the connection ensuring that all the queries in the queue are processed. Please note that this is having a callback function.
connection.end(function(err){
// Do something after the connection is gracefully terminated.
});
The following statement will terminate the assigned socket and close the connection immediately. Also there is no more callbacks or events triggered for the connection.
connection.destroy();

Nodejs cannot load the page when I connect to MySQL?

I can run other programs on node.js with no problem. When I want to connect to MySQL through NODE.js it loads forever when I type nodejs mysqlConnection.js in terminal and http://localhost:8080/ in browser.
My Code is as below:
// Include http module,
var http = require('http'),
// And mysql module you've just installed.
mysql = require("mysql");
// Create the connection.
// Data is default to new mysql installation and should be changed according to your configuration.
var connection = mysql.createConnection({
user: "root",
password: "",
database: "framework"
});
// Create the http server.
http.createServer(function (request, response) {
// Attach listener on end event.
request.on('end', function () {
// Query the database.
connection.query('SELECT * FROM words;', function (error, rows, fields) {
response.writeHead(200, {
'Content-Type': 'x-application/json'
});
// Send data as JSON string.
// Rows variable holds the result of the query.
response.end(JSON.stringify(rows));
});
});
// Listen on the 8080 port.
}).listen(8080);
NB: MySQL connection is correct because I connect to my database via PHP with no problem.
NB: I have a folder named node_modules beside to my js file, inside it I have mysql folder.
I tried to install nodejs through npm:
A request is ended only when the response has been sent.
You're waiting for the end event without ever sending a response (because that response is sent from within the end handler, resulting in a sort of deadlock situation).
As #vkurchatkin points out in the comments, if the request stream is being consumed, the end handler will be called once it has been consumed entirely, independent of the state of the response. In this case, the request wasn't being consumed at all, meaning that the end handler would have been called (as part of the request teardown, probably) only after the response was sent.
So removing the end handler altogether should fix the problem:
http.createServer(function (request, response) {
connection.query(..., function(error, rows, fields) {
// TODO: handle `error`
response.writeHead(200, {
'Content-Type': 'x-application/json'
});
response.end(JSON.stringify(rows));
});
});