Node fork child process and get it's errors - javascript

I am able to fork a child process, but I am having issues seeing what errors are taking place in that file, and I know the file has errors, because I created an object without a closing } so an error should occur. Using the following code, I get nothing (in the console and/or the browser):
var child = require('child_process').fork(full_path, [], {
silent: true,
});
// Tried both of these and nothing gets displayed
child.stdout.on('error', function(data){
res.write(data);
console.log(data);
});
child.stderr.on('error', function(data){
res.write(data);
console.log(data);
});
Here is the child process:
var sys = require('sys');
var mustache = require('mustache');
var template = require('./templates/mypage.html');
sys.puts(template);
var view = {
"musketeers": ["Athos", "Aramis", "Porthos", "D'Artagnan"]
; // Forced error here with no closing "}"
var html = mustache.to_html(template, view);
sys.puts(html);
What do I need to do to display the errors? What am I doing incorrectly?
Edit
Full script:
var sys = require('sys');
var config = require('./server.json');
var url = require('url');
var http = require('http');
function handleRequest(req, res){
var full_path = "";
for(var i in config){
var domain = config[i].server;
if(req.headers.host === domain){
var info = url.parse(req.url);
full_path = config[i].root + info.pathname;
}
}
console.log("Page: " + full_path);
if(full_path != ""){
var child = require('child_process').fork(full_path, [], {
silent: true,
});
child.stdout.on('data', function(data){
res.write(data);
});
child.stdout.on('error', function(data){
res.write(data);
console.log(data);
});
child.stderr.on('error', function(data){
res.write(data);
console.log(data);
});
child.stdout.on('end', function(){
res.end();
});
}else{
res.end();
}
}
var server = http.createServer(handleRequest);
server.listen(3000, function(err){
console.log(err || 'Server listening on 3000');
});

By default all input/output goes back to the parent.
Given parent.js
var fork = require('child_process').fork;
var child = fork('./child');
output and errors from child.js go back to parent
setInterval(function() {
console.log('I am here')
}, 1000);
setTimeout(function() {
throw new Error('oops')
}, 5000);
Like #Plato says, { silent: true } is gonna shut things up

Related

Node.js - Can't send headers after they are sent

The closest issue I've found to mine is here. I believe I'm getting this error from how my .end() calls are set up. Here's the code we're working with:
app.get('/anihome',function(req,res){
var context = {};
function renderPage(context) {
res.render('anihome',context);
}
function addRequestToPage(text) {
context.data = text.toString('utf8');
context.info = JSON.parse(text);
return context;
}
function addAnimeToPage(text) {
context.anime = JSON.parse(text);
return context;
}
function addAnimeRequest(context) {
var options2 = {
host: 'anilist.co',
path: '/api/anime/20631?access_token=' + context.info.access_token,
method: 'GET'
};
https.request(options2, function(restRes) {
restRes.on('data',function(jsonResult) {
//context.anime = JSON.parse(jsonResult);
//console.log(JSON.parse(jsonResult));
console.log(context);
renderPage(context);
});
}).end();
}
function addHeaderRequest(context) {
var options = {
host: 'anilist.co',
path: '/api/auth/access_token?grant_type=client_credentials&client_id='
+ clientID + '&client_secret=' + secretKey,
method: 'POST'
};
https.request(options, function(restRes) {
restRes.on('data', function(jsonResult) {
context = addRequestToPage(jsonResult);
addAnimeRequest(context);
});
}).end();
}
addHeaderRequest(context);
});
I've tried setting up one of the .end()s with a callback, .end(addAnimeRequest(context));, which leaves me with a socket hang up error, so presumably something in my addAnimeRequest function is taking too long?
Is there a better way to make multiple requests to the same website with different options? I'm pretty new to Node.js.
The data event can be emitted more than once. You would need to add a listener for the end event and then pass in all of your data. Example:
https.request(options2, function(restRes) {
var buf = ''
restRes.on('data',function(jsonResult) {
//context.anime = JSON.parse(jsonResult);
//console.log(JSON.parse(jsonResult));
buf += jsonResult
});
restRes.on('end', function() {
// TODO JSON.parse can throw
var context = JSON.parse(buf)
renderPage(context)
})
}).end();

Response is sent before all events are processed in nodejs express module

I am experiencing an issue with express module in node js. Problem statement is response is sent before all events are completed.
In below code, I am calling the function 'commonValidations()' when client hits the respective URI. Inside commonValidations() function, some other functions are invoked internally. But the response is being sent before all validations are completed.
I tried with res.on('end', callbackfunction) then I got some errors with this statement, then I put res.end() function. But still res is sent before all events are completed.
Can someone help me on how I can send the response after all events are processed?
-->app.js (I didn't put the db connection string and connection pool details)
var express = require('express');
var bodyParser = require('body-parser');
var PropertiesReader = require('properties-reader');
var path = require('path');
var http = require("http");
var app = express();
var DB2Pool = require('ibm_db').Pool;
GLOBAL.gCNPool = new DB2Pool();
GLOBAL.gCNString;
GLOBAL.gErrors = {
"teslaRequest":{type : Object},
"error":[]
};
http.createServer(app).listen(3030);
GLOBAL.directoryName=path.resolve(__dirname);
var common = require(directoryName+'/validations/common.js');
app.post("/cfo/taxprofile/stateprofiles/validate", function(req, res){
gCNPool.open(gCNString, function(err, db){
common.commonValidations(db);
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify(gErrors));
}
});
Before stateAbbrValidation function completes, response is sent to the client.
--> common.js
var query = require(directoryName+'/utils/sql_queries.js');
var app = require(directoryName+'/app.js');
module.exports = {
commonValidations:function(db){
stateAbbrValidation(db);
}
};
function stateAbbrValidation(db){
console.log('Query is '+STATE_S01_1);
if(gStateAbbr == null || gStateAbbr == 'undefined')
gErrors.error.push({"errorCode":"E062", "errorDesc":"Invalid State code"});
else{
db.query(STATE_S01_1.replace('<STATE>', gStateAbbr), function(err1, rows){
if(err1){
console.log(err1);
}
if(Object.keys(rows).length == 0){
console.log('Result size '+Object.keys(rows).length);
gErrors.error.push({"errorCode":"E062", "errorDesc":"Invalid State code"});
}
else{
if(gStateCodeValue != null || gStateCodeValue != 'undefined'){
var cdKeys = Object.keys(rows);
var stateCd = rows[cdKeys[0]].STATE_CODE;
if(stateCd != gStateCodeValue){
gErrors.error.push({"errorCode":"E062", "errorDesc":"Invalid State code"});
}
}
}
});
}
/*db.prepare(STATE_S01_1, function(err, stmt){
if(err){
console.log(err);
}
stmt.execute(['CA'], function(err, result, rows){
console.log(err);
console.log(result);
result.closeSync();
console.log(result);
console.log(rows);
});
});*/
}
Try using async.js. It helps in sending a response after all events are processed.
See the following example taken from here :
async.series([
function(callback){
// do some stuff ...
callback(null, 'one');
},
function(callback){
// do some more stuff ...
callback(null, 'two');
}
],
// optional callback
function(err, results){
// results is now equal to ['one', 'two']
});
// an example using an object instead of an array
async.series({
one: function(callback){
setTimeout(function(){
callback(null, 1);
}, 200);
},
two: function(callback){
setTimeout(function(){
callback(null, 2);
}, 100);
}
},
function(err, results) {
// results is now equal to: {one: 1, two: 2}
});
Note: Every function should have a callback and in the end the collective result of all callbacks is sent as an array.

Node.js : how add variable as input in url

i want to use this phantom code but with node.js, but i don't find the equivalent of system.args[1] in node.js
var phantom = require('phantom');
// var page = new WebPage();
// var system = require('system');
// var sBlob = system.args[1];
var sUrl = 'file:///C:/Users/editor.html?Blob='+sBlob;
phantom.create(function(ph) {
ph.createPage(function(page) {
page.open(sUrl, function(status) {
console.log("opened diagram? ", status);
page.evaluate(function() {
return document.getElementById("GraphImage").src;
}, function(result) {
console.log(result)
ph.exit();
});
});
});
}, {
dnodeOpts : {
weak : false
}
});
If you are running your script as $ node script.js theargument
you should be able to get it using
// the first argument is node and
//the second is the script name, none of them should be relevant
var args = process.argv.slice(2);
var sBlob = args[0];

Get array data from angularjs

First of all, sorry for my English. I'm wondering how to get an array data from angularjs, so i can save it with nodejs.
Here is my angularjs script:
angular.module('myAddList', [])
.controller('myAddListController', function(){
var addList = this;
addList.lists = [];
addList.tambah = function(){
addList.lists.push({title:addList.listTitle,greet:addList.listGreet});
addList.listTitle = '', addList.listGreet = '';
}
addList.hapusList = function(list){
addList.lists.splice(addList.lists.indexOf(list), 1);
}
});
and here is my nodejs:
var fs = require("fs");
var d = new Date();
var myJson = {title : {
"lists": []
}
};
function saveFile(){
fs.writeFile( document.getElementById("namafile").value + ".json", JSON.stringify( myJson ), "utf8", function(err) {
if(err) {
return console.log(err);
}else if(!err){
console.log("The file was saved!");
}
});
}
I think "myJson" should be from angularjs array which is "addList.lists = [];" but i dont know how to do that. Or maybe there is an alternative way?
-- Edit --
I think the only solution is to save the array to localStorage and save it to json format. But i have another problem it replace all whitespaces to this character "\" it so annoying.
Here is the following code (add a few changes), let's assume we already stored array to localStorage and save it using nodejs:
var fs = require("fs");
var myJson = {
key: "myvalue"
};
var d = new Date();
var locS = localStorage.getItem("invoice");
function saveFile(){
var nama = document.getElementById("namaFile").value;
fs.writeFile( nama + ".json", JSON.stringify( locS ), "utf8", function(err) {
if(err) {
return console.log(err);
}else if(!err){
console.log("The file was saved!");
}
});
}
myJson = fs.readFile("undefined.json", "utf8", function (err,data) {
if (err) {
return console.log(err);
}
console.log(JSON.parse(data));
console.log(data[2]);});
if i run this code, it give me a nice output
console.log(JSON.parse(data));
and when i tried this
console.log(data[2]);
it give me "\" as an output, btw here is the json file
"{\"tax\":13,\"invoice_number\":10,\"customer_info\":{\"name\":\"Mr. John Doe\",\"web_link\":\"John Doe Designs Inc.\",\"address1\":\"1 Infinite Loop\",\"address2\":\"Cupertino, California, US\",\"postal\":\"90210\"},\"company_info\":{\"name\":\"Metaware Labs\",\"web_link\":\"www.metawarelabs.com\",\"address1\":\"123 Yonge Street\",\"address2\":\"Toronto, ON, Canada\",\"postal\":\"M5S 1B6\"},\"items\":[{\"qty\":10,\"description\":\"Gadget\",\"cost\":9.95,\"$$hashKey\":\"004\"}]}"
Make $http request to your nodejs server like that
angular.module('myAddList', [])
.controller('myAddListController', function($http){//inject $http
var addList = this;
addList.lists = [];
addList.tambah = function(){
addList.lists.push({title:addList.listTitle,greet:addList.listGreet});
addList.listTitle = '', addList.listGreet = '';
}
addList.hapusList = function(list){
addList.lists.splice(addList.lists.indexOf(list), 1);
}
$http.post('your server url',addList).success(function(successReponse){
//do stuff with response
}, function(errorResponse){
//do stuff with error repsonse
}
});
and then you must have route for that request with post type, and then in controller that performs this route request you must perform your file save operations

Express.js server side error message notworking

this is my server side POST code .before my task saving database im find same data in the database using my unique value as service but when i run this code console says ReferenceError: service is not defined
what is wrong here?can some one poine me.please
app.post('/collections/:collectionName', function(req, res, next) {
req.collection.findOne({service: service}, function(e, result){
if(result){
res.send{error: "REQUEST ALREADY EXISTS"};
}
else{
req.collection.insert(req.body, {}, function(e, results){
if (e) return next(e)
res.send(results)
});
}
});
})
update----
button.addEventListener('click', function(e) {
var service_ = service.value;
var amount_ = amount.value;
var name_ = name.value;
var phone_ = phone.value;
var reminder_ = reminder.value;
if (start_pick < end_pick) {
var jsondata = [{
start_time : new Date(start_pick),
end_time : new Date(end_pick),
service : service_,
amount : amount_,
client_phone : phone_,
client_name : name_,
reminder : reminder_
}];
var xhr = Titanium.Network.createHTTPClient();
xhr.setTimeout(10000);
xhr.open("POST", "http://127.0.0.1:3000/collections/appoinments");
xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");
xhr.send(JSON.stringify(jsondata));
xhr.onerror = function() {
Titanium.API.info("Error in connecting to server !!");
alert("Error on connecting to server, Please try again");
};
xhr.onload = function() {
windowPayment.close();
}
The data sent by the POST request will be accessible through req.body, so the variable you are looking for is req.body.service. Also, assuming the function req.collection.findOne uses the property service of the first argument, you should keep the code as following:
req.collection.findOne({service: req.body.service}, function(e, result){
//...
});
Given that an object {req.body.service: ...} is invalid.

Categories