I try to make a little script with node.js (v6.5.0). The first part of this script displays a word randomly found in a list. Then it uses the word (as the key) the display its value (the translation). The script requires the node-redis module. The problem I get seems related to the asynchronous nature of the functions. Is it because the first function is asynchronous that I can't reuse the argument in the nested one? I'm stucked and some directions would be really appreciated.
Here's a snippet of the code...
var redis = require('redis');
var fs = require('fs');
var client = redis.createClient();
client.on('connect', function() {
});
client.randomkey(function (err, word) {
console.log('The question is: ' + word);
client.get('word', function(err, reply) {
if (err) {
console.log(err);
}
//otherwise show the value of this key.
});
});
client.quit();
... and this the error message I get when launching the command node drill.js
The question is: chicken
{ AbortError: Stream connection ended and command aborted. It might have been processed.
at RedisClient.flush_and_error (...thesaurus/node_modules/redis/index.js:350:23)
at RedisClient.connection_gone (...thesaurus/node_modules/redis/index.js:585:14)
at Socket.<anonymous>
(...thesaurus/node_modules/redis/index.js:282:14)
at Socket.g (events.js:286:16)
at emitOne (events.js:96:13)
at Socket.emit (events.js:188:7)
at TCP._handle.close [as _onclose] (net.js:493:12) code: 'NR_CLOSED', command: 'GET', args: [ 'word' ] }
You should call the inner function with the variable, not a string. It will not work like that.
client.randomkey(function (err, word) {
console.log('The question is: ' + word);
client.get(word, function(err, reply) {
if (err) {
console.log(err);
} else {
console.log(reply);
}
// put quiting of the client here NOT at the end of your document
client.quit();
});
});
And then you didn't output the result of the second query.
EDIT: And of course you can't close the connection the way you do, as you would close the connection before the inner function is finished.
Related
I am using a postgres database for my express web server.
I am using the 'pg' library to execute queries on this database.
Here is my connection method :
const db = new Client({
user: 'xxx',
host: 'xxx',
database: 'xxx',
password: 'xxx',
port: xxx,
})
db.connect(err => {
if (err) {
console.error('connection error', err.stack)
} else {
console.log('connected')
}
Then to execute a request I do this:
db.query(MY_REQUEST, function (err, data) {
if (err) throw err;
res.render('hello/world', {
title: 'Hello',
data: data.rows
});
});`
It all works perfectly. But after several minutes without using my website, my connection to the db times out, and I get the following error:
node:events:355
throw er; // Unhandled 'error' event
^
Error: Connection terminated unexpectedly
at Connection.<anonymous> (/usr/src/app/node_modules/pg/lib/client.js:132:73)
at Object.onceWrapper (node:events:484:28)
at Connection.emit (node:events:378:20)
at Socket.<anonymous> (/usr/src/app/node_modules/pg/lib/connection.js:58:12)
at Socket.emit (node:events:378:20)
at TCP.<anonymous> (node:net:665:12)
Emitted 'error' event on Client instance at:
at Client._handleErrorEvent (/usr/src/app/node_modules/pg/lib/client.js:319:10)
at Connection.<anonymous> (/usr/src/app/node_modules/pg/lib/client.js:149:16)
at Object.onceWrapper (node:events:484:28)
[... lines matching original stack trace ...]
at TCP.<anonymous> (node:net:665:12)
How could I do to reconnect automatically when the connection is cut or when a request fails?
You should attach an error-handler in order to prevent the unhandled error crashing your app. It's as simple as:
db.on('error', e => {
console.error('DB error', e);
});
As to why the error happens we need more details, looks like it could be a connection reset due to idle-timeout?
You can create a function to control if you're connected to database or not, before you continue with your main function.
Create a function for controlling database connection status, reconnecting etc. and before you run a database related function, first start that middle function and wait for result, after that you can continue using database again.
If you want(which should be prefered way mostly), create that middle function as an async function and return a promise, when using that function wait for that function.
N need some help here using this API.
I'm trying to get data from Poloniex API for NodeJS (npm Install)
I'm confuse with which parameter i have to pass here in the callback parameter, I'm new in nodeJS, so maybe im getting wrong what i need as a callback.
This method is used for the API to fetch data from the poloneix web, to calculate basic things, currently i need the information of the Pair BTC/USD, here is the property of the poloneix instance:
returnChartData(currencyA, currencyB, period, start, end, callback);
It is Declared as this in the poloneix.js file:
returnChartData: function(currencyA, currencyB, period, start, end, callback) {
var parameters = {
currencyPair: joinCurrencies(currencyA, currencyB),
period: period,
start: start,
end: end
};
What do I need to use in as a callback parameter for this Function?
var response = poloniex.returnChartData('BTC','LTC',300,1510570525,1510638955,**(¿here?)**)
fs.appendFile('BTC_pair.json', response, function(err) {
if(err) {
console.log('there was an error: ', err);
return;
}
console.log('BTC Pair Saved');
});
I know it is Wrong, but i tried to use simple Fucntions, for example as a Timer to explore what i need to pass as a callback, and im getting this error while running executing my node file:
D:\Projects\NodeJS\ZenBot\ZenBot_v2\poloniex.js\lib\poloniex.js:79
callback(err, body);
^
TypeError: callback is not a function
at Request._callback (D:\Projects\NodeJS\ZenBot\ZenBot_v2\poloniex.js\lib\poloniex.js:79:7)
at Request.self.callback (D:\Projects\NodeJS\ZenBot\ZenBot_v2\poloniex.js\node_modules\request\request.js:122:22)
at emitTwo (events.js:106:13)
at Request.emit (events.js:194:7)
at Request.<anonymous> (D:\Projects\NodeJS\ZenBot\ZenBot_v2\poloniex.js\node_modules\request\request.js:888:14)
at emitOne (events.js:101:20)
at Request.emit (events.js:191:7)
at IncomingMessage.<anonymous> (D:\Projects\NodeJS\ZenBot\ZenBot_v2\poloniex.js\node_modules\request\request.js:839:
12)
at emitNone (events.js:91:20)
at IncomingMessage.emit (events.js:188:7)
And in the poloniex.js File here in the constructor is where the error is comming:
_request: function(options, callback) {
if (!('headers' in options)) {
options.headers = {};
}
options.json = true;
options.headers['User-Agent'] = Poloniex.USER_AGENT;
options.strictSSL = Poloniex.STRICT_SSL;
request(options, function(err, response, body) {
// Empty response
if (!err && (typeof body === 'undefined' || body === null)){
err = 'Empty response';
}
callback(err, body); <----- THIS LINE
});
Do I need to declare any function? or something?
In my express app i have the route below:
router.get('/generatedData', function (req, res) {
res.setHeader('Connection' , 'Transfer-Encoding');
res.setHeader('Content-Type' , 'text/html; charset=utf-8');
res.setHeader('Transfer-Encoding' , 'chunked');
var Client = someModule.client;
var client = Client();
client.on('start', function() {
console.log('start');
});
client.on('data', function(str) {
console.log('data');
res.write(str);
});
client.on('end', function(msg) {
client.stop();
res.end();
});
client.on('err', function(err) {
client.stop();
res.end(err);
});
client.on('end', function() {
console.log('end');
});
client.start();
});
On first call everything works fine (console)
We've got ourselves a convoy on port 3000
start
data
data
data
data
data
...
data
end
GET /generatedData 200 208.426 ms - -
I get all the data and res.end() is being called and successfully closes the request.
The problem starts after first request. I make the exact same request (new one of course) and i get the following error (console):
start
data
data
data
events.js:160
throw er; // Unhandled 'error' event
^
Error: write after end
at ServerResponse.OutgoingMessage.write (_http_outgoing.js:439:15)
at Client.<anonymous> (/Users/xxxx/projects/xxxx/routes/index.js:33:17)
at emitOne (events.js:96:13)
at Client.emit (events.js:188:7)
at FSWatcher.<anonymous> (/Users/xxxx/projects/xxxx/lib/someModule.js:116:32)
at emitTwo (events.js:106:13)
at FSWatcher.emit (events.js:191:7)
at FSEvent.FSWatcher._handle.onchange (fs.js:1412:12)
[nodemon] app crashed - waiting for file changes before starting...
This happens without res.end() being called.
I manage to get some data before the crash.
How can i get this error without res.end() being called at all?
Do i somehow save the previous res instance?
Thanks,
Asaf
Have the same problem. My module was extened by EventEmitter and each time i catch event in router - it stays there, end on second call there are two eventlisteners not one. Setting "once" instead of "on" - worked for me.
client.once('start', function() {
console.log('start');
});
instead of
client.on('start', function() {
console.log('start');
});
I'm trying to connect a Node.js app with a PostgreSQL server. It seems that no matter what I use, I end up with the same error:
bundle.js:16177 ERROR: TypeError: net.Stream is not a constructor
at new Connection (bundle.js:10133)
at new Client (bundle.js:9704)
at Object.create (bundle.js:11308)
at Pool._createResource (bundle.js:510)
at Pool.dispense [as _dispense] (bundle.js:498)
at Pool.acquire (bundle.js:573)
at Pool.pool.connect (bundle.js:11359)
at PG.connect (bundle.js:10876)
at bundle.js:1642
At first I was declaring a new pg.Client() like the example in the documentation here, but got the above error discovered that might be a bad idea according to this stack overflow post.
I tried using pg.connect():
var pg = require('pg'); //postgresql dependency
var connectionString = "postgres://postgres:thisissuchagoodpassword#PostgreSQL/localhost:5432/Milestone1DB"
console.log("Initiating...");
//var connectionString = "postgres://postgres:thisissuchagoodpassword#PostgreSQL9.6/localhost:5432/Milestone1DB";
//var client = new pg.Client();
//connect to the database
console.log("Attempting to connect to the database");
pg.connect(function (err, client, done)
{
if(err)
{
console.log("Error connecting to the database.");
throw err;
}
client.query("SELECT DISTINCT state FROM business ORDER BY state", function (err, result)
{
if(err)
{
console.log("Query resulted in an error.");
throw err;
}
console.log(result.rows[0]);
client.end(function (err)
{
if(err)
{
console.log("Error disconnecting from the databse.");
throw err;
}
});
});
});
Here is the pg-promise code that I tried:
var pgp = require('pg-promise');
var cn = {
host: 'localhost', // server name or IP address;
port: 5432,
database: 'Milestone1DB',
user: 'postgres',
password: 'thisissuchagoodpassword'
};
var db = pgp(cn); // database instance;
db.any("select distict state from business order by state;")
.then(data => {
console.log("DATA:", data);
})
.catch(error => {
console.log("ERROR:", error);
});
I must be missing something, but I don't know where to look. Thank you to anyone who can help me figure out what this error means.
Make sure you are not crossing a context boundary that is corrupting the net prototype chain and stripping away methods like Stream(). I ran into a similar unhandled Promise exception w Node 7.5 and pg-live-select. However it was intermittent because of the way the net reference was being passed around. I ended up using V8 inspector and putting a 'debugger' statement directly above line 13 in connection.js to catch the corruption.
node_modules/lib/connection.js:13
this.stream = config.stream || new net.Stream();
^
TypeError: net.Stream is not a constructor
at new Connection (node_modules/pg-live-select/node_modules/pg/lib/connection.js:13:34)
at new Client (node_modules/pg-live-select/node_modules/pg/lib/client.js:26:37)
at Object.create (node_modules/pg-live-select/node_modules/pg/lib/pool.js:27:24)
at Pool._createResource (node_modules/generic-pool/lib/generic-pool.js:325:17)
at Pool.dispense [as _dispense] (node_modules/generic-pool/lib/generic-pool.js:313:12)
at Pool.acquire (node_modules/generic-pool/lib/generic-pool.js:388:8)
at Pool.pool.connect (node_modules/pg-live-select/node_modules/pg/lib/pool.js:78:14)
at PG.connect (node_modules/pg-live-select/node_modules/pg/lib/index.js:49:8)
at LivePg._updateQuery (node_modules/pg-live-select/index.js:295:6)
at node_modules/pg-live-select/index.js:160:14
at Array.forEach (native)
at Timeout.performNextUpdate [as _onTimeout] (node_modules/pg-live-select/index.js:159:23)
at ontimeout (timers.js:365:14)
at tryOnTimeout (timers.js:237:5)
at Timer.listOnTimeout (timers.js:207:5)
I am using Redis and consulting it from nodejs, using the module Redis.
When i exec a client.multi() and the redis server is down the callback doesn't send the error and the nodejs app terminates.
This is the error
/Users/a/db/node_modules/redis/index.js:151
throw callback_err;
^
TypeError: Cannot read property 'length' of undefined
at Command.callback (/Users/a/db/node_modules/redis/index.js:1098:35)
at RedisClient.flush_and_error (/Users/a/db/node_modules/redis/index.js:148:29)
at RedisClient.on_error (/Users/a/db/node_modules/redis/index.js:184:10)
at Socket.<anonymous> (/Users/a/db/node_modules/redis/index.js:95:14)
at Socket.EventEmitter.emit (events.js:95:17)
at net.js:441:14
at process._tickCallback (node.js:415:13)
this is my code:
Constructor class
var redis = require('redis');
var client;
function Redis(){
client = redis.createClient();
client.on("error", function (err) {
console.log("Error " + err);
});
}
Redis.prototype.multi = function(commands,callback){
var err = null;
client.multi(commands).exec(function (error, res) {
if(error){
process.nextTick(function(){
callback(error,null)
})
}else{
process.nextTick(function(){
callback(null,res)
})
}
});
}
FYI, I ran across this in an old lib that depended on old version of node_redis.
This issue was a bug and was fixed in v0.9.1 - November 23, 2013: https://github.com/mranney/node_redis/pull/457
I think that people are still reaching here... (not sure if this answers this specific question directly, but I assume people reaching here since the multi.exec() returns true / the event loop is not waiting for it's response.
After the fixes that went in (in node-redis), it is possible to wrap the result of exec with Promise, and then you will be sure that the result will include the replies from the multi.
So, you can add some redis commands to the multi:
await multi.exists(key);
await multi.sadd(key2,member);
And then in the result do something like:
return new Promise((resolve, reject) => {
multi.exec((err, replies) => {
if (err) {
reject(err);
}
return resolve(replies);
});
});
Otherwise, if you will just do: const reply = await multi.exec();
it will just return you true, and not the replies
** Important to mention - this refers to 'async-redis' and 'node-redis'