const client = http2.
connect('https://domain.doesnt.exist').
on('error', e => {
console.error(e.message);
});
On Node.js 13.6.0, even when provided an error listener, the above code would crash the entire process.
How will I be able to avoid it?
you can use uncaughtException event to log all exceptions not been caught..
process.on('uncaughtException', err => {
console.log(err.message);
console.log(err.stack);
process.exit(1)
})
Related
I am trying to add a set to a redis database in a node.js app like this:
let redisConnect = async () => {
redisClient.on('error', (err) => {
console.log('Redis Client Error', err);
});
redisClient.on('ready', () => console.log('Redis is ready'));
await redisClient.connect();
redisClient.sadd(['tags', 'angularjs', 'reactjs', 'nodejs'], function(err, reply) {
console.log(reply);
});
};
redisConnect();
This error is thrown:
TypeError: redisClient.sadd is not a function
I am able to set other Redis database types on this client like list or string.
I do not understand fully how I solved this problem. I switched from the redis library to ioredis and got rid of:
await redisClient.connect();
and added 'await' to
await redisClient.sadd(['tags', 'angularjs', 'reactjs', 'nodejs'], function(err, reply) {
console.log(reply);
});
I think the redisClient.connect( ) might have been redundant. This threw an error when I switched to ioredis :
Error: Redis is already connecting/connected
Possibly someone will have an explanation for this solution.
I have a problem with an error appearing on one of my express route. I handled it by using express next but then the error is also caught by my global process.on('uncaughtException') that is implemented to shut-down my server. Hope this example is clear.
app.get("/api/users", async (req, res, next) => {
try {
// (1) This call will throw an error
const users = await getUsers()
res.send(users)
}
catch (err) {
// (2) The error will be correctly caught by this try catch and send to the error handler
next(err)
}
})
// (3) The problem is that it will be also caught by this and my server will stop
// I don't want this since I've already handled it using express
process.on('uncaughtException', (err: Error) => cleanShutdown(`Uncaught exception`, err))
Is it possible to avoid going to (3) when I have already handled the error?
I am trying to catch connection failed error if the given host is not correct or cannot be reached.but it seems this error is logging from websocket itself and is not related to shocket io it self.
WebSocket connection to
'ws://file/socket.io/?EIO=4&transport=websocket' failed: Error in
connection establishment: net::ERR_NAME_NOT_RESOLVED
I tried this catch errors naming events :
socket.on("connect_error", (error)=>{
console.log(error)
})
socket.on("connect_failed", (error)=>{
console.log(error)
})
socket.on("error", (error)=>{
console.log(error)
})
but none of them are working.
research :
https://github.com/socketio/socket.io-client/issues/1097
I tried this option on my socketio client instance :
const socket = require('socket.io-client')('https://somefoo.com', {
transports: ['websocket'],
rejectUnauthorized: false
})
What you can try to do, is to use the socket.io manager which is catching errors of a higher level.
https://socket.io/docs/v3/client-api/#Event-%E2%80%98error%E2%80%99
https://socket.io/docs/v3/client-api/#Manager
const manager = new Manager('https://somefoo.com')
const socket = manager.socket('/')
manager.on('error', (error) => {
// Fired upon a connection error.
console.log('socket error')
})
socket.on('connect_error', (error) => {
// Fired when an namespace middleware error occurs.
console.log('connection error')
})
the answer to this question: How to get node to exit when mongo connect fails contains async/wait code for a connection
however, my code (running on node v11.5.0 and mongodb v3.1.13) is failing to catch:
(async function() {
let db;
try {
db = await MongoClient.connect(uri, { useNewUrlParser: true });
console.log("RETURN", db);
} catch (err) {
console.log('EXITING');
process.exit(1);
}
}());
to prove the point I intentionally give a uri without credentials:
mongodb://undefined#cluster0-shard-00-00-z4j9e.azure.mongodb.net:27017,cluster0-shard-00-01-z4j9e.azure.mongodb.net:27017,cluster0-shard-00-02-z4j9e.azure.mongodb.net:27017/test?ssl=true&replicaSet=Cluster0-shard-0&authSource=admin&retryWrites=true
and what I get is output like this:
/Users/ekkis/dev/mongo/node_modules/mongodb/lib/topologies/replset.js:346
throw err;
^
MongoError: password must be a string
at passwordDigest (/Users/ekkis/dev/mongo/node_modules/mongodb-core/lib/auth/scram.js:63:43)
at ScramSHA1.ScramSHA.auth (/Users/ekkis/dev/mongo/node_modules/mongodb-core/lib/auth/scram.js:175:25)
at authenticate (/Users/ekkis/dev/mongo/node_modules/mongodb-core/lib/connection/pool.js:232:17)
at authenticateLiveConnections (/Users/ekkis/dev/mongo/node_modules/mongodb-core/lib/connection/pool.js:819:7)
at /Users/ekkis/dev/mongo/node_modules/mongodb-core/lib/connection/pool.js:864:5
at waitForLogout (/Users/ekkis/dev/mongo/node_modules/mongodb-core/lib/connection/pool.js:855:34)
at Pool.auth (/Users/ekkis/dev/mongo/node_modules/mongodb-core/lib/connection/pool.js:862:3)
at Server.auth (/Users/ekkis/dev/mongo/node_modules/mongodb-core/lib/topologies/server.js:931:20)
at auth (/Users/ekkis/dev/mongo/node_modules/mongodb-core/lib/topologies/replset.js:1474:19)
at ReplSet.auth (/Users/ekkis/dev/mongo/node_modules/mongodb-core/lib/topologies/replset.js:1492:5)
so if the error had been caught, the console should have displayed the word 'EXITING', but does not. additionally, I contend an exception was thrown because otherwise the returned value would have been printed, which it was not
how can this be? what do I need to do to get it to work?
* Appendix I *
In fact, the promises version of this exhibits the same odd behaviour, it doesn't catch:
MongoClient
.connect(uri, { useNewUrlParser: true })
.then(dbc => {
console.log('SUCCESS');
})
.catch(err => {
console.log('EXITING');
process.exit(1);
});
and yes, I tested the callback version, which also suffers the same malady. Incidentally, passing an empty string for the uri works well. I don't get it
* Appendix II *
In fact, the problem seems to be particular to the credentials passed i.e. if I pass:
mongodb://x:y#cluster0-shard-[...]
I catch a "MongoError: authentication fail" as expected. passing:
mongodb://#cluster0-shard-[...]
interestingly returns a connection but credentials missing a ":" fail in this odd way, so:
mongodb://ekkis#cluster0-shard-[...]
fails to catch
Looks to me like it's a bug with however MongoClient is setting up its connections. You won't be able to use try & catch to handle asynchronously thrown errors within MongoClient code.
const {MongoClient} = require("mongodb");
process.on("uncaughtException", (err) => {
console.log("process err", err);
process.exit(1)
})
async function run () {
let db;
try {
// connection url will throw because password isn't provided
db = await MongoClient.connect("mongodb://myUsername:#localhost", { useNewUrlParser: true });
} catch (err) {
console.log('Exiting from thrown error', err);
process.exit(1);
}
}
run();
Here's a simplified example of what's happening -- the error will end up "uncaught" and caught by the uncaughtException handler
process.on("uncaughtException", (err) => console.log("uncaught", err));
try {
setTimeout(() => {
throw new Error("asynchronously thrown error");
})
} catch (err) {
console.log("Error will not be caught here")
}
When I was using mongo version 3.6.1, it was not an issue and i was able to handle the thrown exception using catch. But after a few days on another project this type of error occurred and was showing as the error thrown from
%project_folder%/node_modules/mongodb/lib/utils.js:668
(Don't mind about the slash in the path string.)
The mongodb version this time is 3.6.3. Upon checking the code in that file at the mentioned line I found the below piece of code. where the caught error is again being thrown.
fn(function(err, res) {
if (err != null) {
try {
callback(err);
} catch (error) {
return process.nextTick(() => {
throw error;
});
}
return;
}
callback(err, res);
});
I changed the throw error to console.error(error) and the problem got resolved. But still you need to be caught somewhere in our code where connect function is called.
I think this is because the above piece of code is checking for the presence of error and passing it to the callback function and then again throwing the same error again. I suppose it is the MongoDB driver developer community's responsibility to resolve this issue.
In my application i want to create own module to capture my application error using uncaughtException.If i create uncaughtException in same module means its capturing errors but if i create that uncaughtException in separate module.Then call that module means its not capturing erros.Can anyone help me to fix this issue.
module1.js
var errorModule=require('./module2');
var err = new Error('Something went terribly wrong');
errorModule.captureError(err);
module2.js
module.exports.captureError=function(err){
process.on('uncaughtException', function(err) {
console.log(err);
});
}
Try this:
// module1.js
var errorModule=require('./module2');
errorModule.captureErrors();
throw Error('Something went terribly wrong');
// module2.js
module.exports.captureErrors = function() {
process.on('uncaughtException', function(err) {
console.log('an error occurred', err);
});
};
A few things to notice:
process.on('uncaughtException', ...) installs an event handler to catch uncaught exceptions; your code tries to pass an error to it, but that seems to defeat what you're writing ('to capture my application error using uncaughtException');
Uncaught exceptions are errors which are thrown (throw Error(...));
If you want the code in your module1 to work, module2 needs to look like this:
module.exports.captureError = function(err) {
console.log(err);
};
But that has nothing to do with uncaughtException.