APP Crashing in Node JS if the json request is undefined - node.js

I am new to Node JS and I had done a lot of research and couldnt find any solution for the same. This is my code below
if(msg.body == 'Track ' + slug){
const str = msg.body;
const slug = str.substring(str.indexOf("Track") + 6); // 01-2020
var http = require('https');
var options = {
host: 'example.com',
path: '/example/example?id=' + slug
};
callback = function(response) {
var str = '';
response.on('data', function (chunk) {
str += chunk;
});
response.on('error', (err) => {
msg.reply('Error!');
})
response.on('end', function () {
var jsonObject = JSON.parse(str);
msg.reply('Current status of ' + slug + ': ' + jsonObject[0]['body']);
});
}
http.request(options, callback).end();
}
So if I enter Track and a value the value will be captured and then sent in the json request. The json request very much works unless there is an error where the app crashes. This becomes a very big problem. So If I enter the wrong value then the app crashes saying undefined in the log. I want it to msg.reply the error instead of the app crashing. Please help me out. Thank you in advance

Like what commenter Joe says you should wrap your response code in a try/catch block. That will let you print out the error message properly.
try {
.. code youre expecting to hopefully not crash ..
} catch (error) {
msg.reply('Error!', error);
}

Here are some helpful examples for node
Handling Errors
try {
//lines of code
} catch (e) {
msg.reply('Error!');
console.log(e);
}
Handling uncaught exceptions
process.on('uncaughtException', err => {
console.error('There was an uncaught error', err)
process.exit(1) //mandatory (as per the Node.js docs)
})
Exceptions with promises
doSomething1()
.then(doSomething2)
.then(doSomething3)
.catch(err => console.error(err))
With async functions
async function someFunction() {
try {
await someOtherFunction()
} catch (err) {
console.error(err.message)
}
}
Learn more here https://nodejs.dev/learn/error-handling-in-nodejs

Related

Node.js in aws callback variable

Hi im trying to use callback for variable external use outside the function but something is wrong, i think my callback is not so correct as i think:
function latitude(callback){
var mylat;
const https = require('https');
https.get('https://url_of_my_json', (resp) => {
let data = '';
// A chunk of data has been recieved.
resp.on('data', (chunk) => {
data += chunk;
});
// The whole response has been received. Print out the result.
resp.on('end', () => {
mylat = JSON.parse(data).results[0].geometry.location.lat;
callback(mylat);
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});
}
var mylat = latitude(); // variable i want to use for the rest of code
Thanks
The syntax of the callback is incorrect.
here is the example, for better understanding of callback Try this example as simple as you can read, just copy save newfile.js do node newfile to run the application.
function myNew(next){
console.log("Im the one who initates callback");
next("nope", "success");
}
myNew(function(err, res){
console.log("I got back from callback",err, res);
});
happy coding :)

Incorrect order execution on my server TCP (node.js)

I attached my server code:
var net = require('net');
var sqlite3 = require('sqlite3').verbose();
var db = new sqlite3.Database('MyBBDD.db');
var prueba = '';
function get_kw_actual(nombre,callback){
stmt = db.prepare("SELECT kw_actual FROM usuarios WHERE usuario = ?");
stmt.bind(nombre);
stmt.get(function(error,row){
if(error){
throw err;
}
else{
if(row){
entero=row.kw_actual;
callback(entero);
}
else{
console.log("error");
}
}
});
}
var server = net.createServer(function(socket) {
console.log("Recibo peticion");
socket.on('data', function (data) {
get_kw_actual('Pepe',function(resultado){
console.log('resultado es: ' + resultado);
prueba = '' + resultado;
})
socket.write(prueba);
});
socket.on('close', function () {
console.log('Connection closed');
});
});
server.listen(1337, '192.168.1.101');
In my server, I receive a request, I call to my function "get_kw_actual" I get a number of my database and finally I respond with the result.
The problem is that it runs first "socket.write(prueba);" than:
stmt.get(function(error,row){
if(error){
throw err;
}
else{
if(row){
entero=row.kw_actual;
callback(entero);
}
else{
console.log("error");
}
}
});
So... the execution is not executed in the correct order and the result is not correct.
Somebody know how can I solve it?
Thanks in advance.
Best regards.
Node.js code runs asynchronously. The code in the callback get_kw_actual returns immediately but the callback will run at some later time, when the database operation has completed. What you want to do is put socket.write inside of the callback, like this:
socket.on('data', function (data) {
get_kw_actual('Pepe',function(resultado){
console.log('resultado es: ' + resultado);
socket.write(resultado);
})
});
Also note that you're using a global variable prueba in your code, which will get clobbered when you have multiple clients running against your server. Do not use global variables like this in node.

Node.js and MongoDB on MongoLab: "Sockets Closed" On Every Insert

I'm trying to do something relatively simple and am running into a "server ...-a.mongolab.com:36648 sockets closed" error all of a sudden every time I try to do an "insert".
Reads seem to work without error, but inserts seem to get an error every time and I'm not sure if it's my code (which recently underwent minor changes), or a reliability problem with the free server I'm using at MongoLab (which recently showed itself to be down for a few minutes).
Oddly enough, the record itself seems to save okay, I just get the error back!
Can anyone see an issue with my code, or could this be something else?
var mongoClient = require('mongodb').MongoClient;
var http = require('http');
var connectionString = "...";
var pictureWallsCollectionName = 'PictureWalls';
//this is what barfs. see *** details
exports.saveWall = function (req, res) {
//reformat
var toSave = {
_id: req.body.wallId,
pictures: req.body.pictures
};
var status;
mongoClient.connect(connectionString, function (err, db) {
if (err) { return console.error(err); }
var collection = db.collection(pictureWallsCollectionName);
//*** no err yet... ***
collection.insert(
toSave,
function (error, response) {
//*********************
//*** err here! ******
//*********************
db.close();
if (error) {
console.error(error);
//bad
status = 500;
}
else {
console.log('Inserted into the ' + collection_name + ' collection');
//good
status = 200;
}
});
response.status(status).end(http.STATUS_CODES[status]);
});
}
//this seems to work pretty reliably. including it just in case it's relevant
exports.findByWallId = function (req, res) {
var id = req.params.id;
console.log('Retrieving wall: ' + id);
mongoClient.connect(connectionString, function (err, db) {
if (err) { return console.dir(err); }
var collection = db.collection(pictureWallsCollectionName);
collection.findOne(
{ _id: id },
function (err, item) {
db.close();
if (err) {
console.error(err);
//something bad happened
var status = 500;
res.status(status).end(http.STATUS_CODES[status]);
}
else {
console.log('Found wall with ID ' + id);
//reformat and send back in the response
res.send({
wallId: item._id,
pictures: item.pictures
});
}
}
);
});
};
EDIT: Part of my original issue was duplicate parameter names. See the linked question for detail.
ORIGINAL RESPONSE:
The issue ended up being that I was calling:
res.status(status).end(http.STATUS_CODES[status]);
...before the async insert was finished, so it barfed.
However, I'm not exactly sure how to issue the response in this case. See my new question here:
How Do I Properly Issue Response To Post When Waiting For Async Method To Complete?

How can I unit test node.js functions with Mocha?

I am trying to test a function that looks like:
function sendVerifySms(patientId, data) {
var smsNumber = data.smsNumber;
var verifyCode = ((Math.random() * 1000000) | 0).toString();
var sql = "UPDATE [patient]";
sql += " SET phone_sms_verify_code = '" + verifyCode + "',";
// verification must take place within a one hour period
sql += " phone_sms_verify_code_expire = '" + moment.utc().add(1, 'hour').formatSqlDatetime() + "',";
sql += " phone_sms_verified = 0,"
sql += " phone_sms = '" + escapeSql(smsNumber) + "'";
sql += " WHERE id = " + escapeSql(patientId.toString());
return sqlServer.query(sql).then(function(result) {
twilioClient.sendMessage({
to: smsNumber,
from: twilioUser.verifyNumber,
body: verifyCode
}).then(function(res) {
console.log('sent verification');
return verifyCode;
}).fail(function(err) {
console.log('error sending verification');
console.log(err);
return err;
});
}).fail(function(err) {
console.log(err);
return err;
});
}
Easy enough, right? Well, first I need to decide what EXACTLY I'm testing for.
That the sql command matches the format given some data
That the twilioClient.sendMessage has been called.
Here is what I have for my test so far:
var should = require('should');
var methods;
var mockery = require('mockery');
var sinon = require('sinon');
describe('RPC Methods', function() {
before(function() {
mockery.enable();
mockery.registerMock('msnodesql', {
open: function() {
return true;
}
});
mockery.registerMock('../../db/sqlserver', {
query: function() {
return {
then: function() {
return true;
}
}
}
});
methods = require('../../../rpc/methods');
});
it('should send a verify SMS', function() {
var data = {
}
methods.sendVerifySms(1, data);
should(1).equal(1);
});
});
So now I'm a bit lost from here. I have a ton of require and since I want to isolate my individual functions for testing, I figured something like mockery would work. Where do I go from here?
If anything is unclear, please post a comment and I'll clarify.
Thanks!
With mocha tests you have an optional done callback that makes testing async functions easier, like this:
it('should send a verify SMS', function(done) {
var data = {};
var code = 1;
methods.sendVerifySms(code, data)
.then(function(actualCode) {
should(actualCode).equal(code);
done();
});
});
I would also have some feedback to offer on the async function you're testing. First I'd say you don't have to nest promise chains the way you are, and in this case its probably better that you didn't. If you simply return a promise from within a promise callback, you can chain it at the same level, like this:
return sqlServer.query(sql).then(function(result) {
return twilioClient.sendMessage({
to: smsNumber,
from: twilioUser.verifyNumber,
body: verifyCode
});
}).then(function(res) {
console.log('sent verification');
return verifyCode;
}).fail(function(err) {
console.log(err);
throw err;
});
Second, in the error handler you had before you were simply returning the err. This is probably a bad idea because it tells the consumer of your promise that everything is hunky dory and that they should proceed as such. Throwing an error on the other hand will allow that consumer to handle the error however they want in their own .fail block.

response is in junked format in node.js

I am developing an API using Node.js. In my application when i hit an URL though browser i gto JSON response in my browser perfectly.. But when i get the response through my node.js code, its coming as junk.
Consider i am hitting the following url in browser:
localhost:2000/xxxxx/rrrrr/ggggg
I am receiving perfect output.
The following is the node.js code:
proxyReq.on("response", function(proxyRes) {
var body = ''
try{
proxyRes.on("data", function(chunk) { //Capture API response here---revisit
body += new Buffer(chunk, 'binary').toString();
//console.log("cccc=" +chunk)
/*zlib.unzip(chunk.toString(), function(err, chunk){
console.log("Inside zliib");
if (!err){
console.log('Response'+chunk.toString())
} else {
console.log("Inside zlib error");
}
});*/
//body = chunk.toString();
//console.log(chunk.toString('utf-8'));
console.log('cccccccc=' +body);
});
}catch(err){
console.log("errrr=" +err.stack);
}
}
Here the 'body' is printing as some junked data. I tried for "utf-8" and "binar" nothing works. Help me to solve this. Thanks in advance.
Mu Junked Data:
Ys��ǿJ����}񛃉/c�؎}�%�ld� a�T��mIL�Z� ]�T��I�r����ߕ�h4��ϕ�7t{�Q4��8���\�L�N؛T��VWM�r
?W&Q��N&/Q����|�W9??W��t�b�n:t>:��(t��G��K��w��=��r\���_��W�N�c��{���u�ۺU���m�^���z�'�ǫ��LFQ�uc���s�>��f
I didn't install using npm:
Third party code regarding ProxyReq:
var ended, mod, proxyReq, req_options;
if (err) {
return _this.error(err, req, res);
}
mod = req.api.data.protocol === "https" ? https : http;
req_options = _this.getHttpProxyOptions(req);
req_options.agent || (req_options.agent = new mod.Agent({
maxSockets: 100,
rejectUnauthorized: req.api.data.strictSSL
}));
_this.logger.debug(("Backend: " + req_options.method + " to ") + ("'" + req.api.data.protocol + "://") + ("" + req_options.host + ":" + req_options.port + req_options.path));
proxyReq = mod.request(req_options);
proxyReq.setTimeout(req.api.data.endPointTimeout * 1000, function() {
var e;
e = new Error("ETIMEDOUT");
e.code = "ETIMEDOUT";
proxyReq.emit("error", e);
return proxyReq.abort();
});
ended = false;
I found your problem. This is the documentation of event response for http/https
Emitted when a response is received to this request. This event is emitted only once. The response argument will be an instance of http.IncomingMessage.
And http.IncomingMessage is a ReadableStream.
After that, you should use this two events of stream to convert this into String :
Event: 'data'
Event: 'end'
For stream.on('data', ...) you should collect your data data into either a Buffer (if it is binary) or into a string.
For on('end', ...) you should call a callback with you completed buffer, or if you can inline it and use return using a Promises library.
Example, for you, you can change your proxyReq.on("response") callback content by this :
var Buffer = require('buffer').Buffer;
proxyReq.on("response", function(chunk) {
//proxyRes.setEncoding ('utf8');
var body = '';
chunk.on('data', function(data) {
body += new Buffer(data, 'binary').toString();
});
chunk.on('end', function () {
// callback
});
chunk.on('error', function (err) {
// catchable error
});
});
To simplify you request part, I recommand you to use the node-request package : https://github.com/mikeal/request

Resources