I'm trying to implement libp2p inside an electron application, which (obviously) has node support turned on.
I tried catching errors with the following code:
const errorHandle = `
window.onerror = (err) => {
console.log(err);
};
process.on("uncaughtException", function (err) {
console.log(err);
});
process.on("unhandledRejection", function (err) {
console.log(err);
});
console.log("Injected startup code")`
await mainWindow.loadFile("./public/index.html");
await mainWindow.webContents.executeJavaScript(errorHandle);
However if I throw an error deliberately, or by accident, the app crashes, and gets reloaded, and I can't see the error, because chrome devtools clears its console, and prints out the "Devtools disconnected" message.
2 examples of error throwing:
console.error("test");
node.connect("INVALID_ADDRESS");
How can I properly handle errors, so electron (or node) doesn't crash?
As it turns out, the error was handled correctly, however the event was connected to a form, which by default refreshes the page if submitted. I had to cancel the default event by:
<form onsubmit="return false" on:submit={submit}></form>
Related
My backend login process is running on a Nodejs 12.16.1. The code is following:
router.post("/elogin", async (req, res) => {
try {
if (!req.body.userName || !req.body.password) throw new Error("No match"); //<<==this line causes error and jump to catch
let emp = await Employee.findOne({where: {username, password}});
if (!emp) throw new Error("No match!");
return res.status(200).send(_.pick(emp, ['id', 'cell', 'cell_country', 'name']))
} catch(err) {
return res.status(400).send("Hi Not working right now"); //<<===this return stuck and never come out.
}
});
In debug the code stuck at drainQueues in Bluebird which is a promise library according to online info. The execution never ends and stuck here. This is a normal return and I don't see how it shall be stuck.
The front end is React and Fetch. The action type does not matter. The get is stuck as well.
You try to use postman to see if it returns. If there is, then there may be a problem with the backend code
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)
})
I'm building a small web application using Node.js, Express, Mongoose, and Passport. Everything is working, but I'm trying to make the application fail gracefully if the MongoDB user database is not available. The application makes a database call every time it deserializes the user out of the session, so I can't do much if the database is down. I just want to display a general error page to the user and recover if/when the database is back up.
Right now, in my local implementation, if I take down the MongoDB server (by just hitting CTRL-C) and then try to, say, reload a page with authentication, sometimes I get my global error page but mostly the application just hangs without generating any errors or console logs (despite the addition of multiple console.log() statements at key failure points, see below) and continues to hang on all future requests. If I then restart the MongoDB server, the application doesn't recover.
The complete source code is here but select code snippets are below.
Mongoose connection:
mongoose.connect(mongodbURI, mongodbConnectOptions);
// Log database events to the console for debugging purposes
mongoose.connection.on('open', function () {
console.log("Mongoose open event");
});
mongoose.connection.on('close', function () {
console.log("Mongoose close event");
});
mongoose.connection.on('connected', function () {
console.log("Mongoose connected event");
});
mongoose.connection.on('disconnected', function () {
console.log("Mongoose disconnected event");
});
mongoose.connection.on('error',function (err) {
console.log("Mongoose error event:");
console.log(err)
});
The Passport deserializeUser() call:
passport.deserializeUser(function(id, done) {
console.log("Attempting to deserialize user")
User.findById(id, function(err, user) {
if (err) console.log("Database error inside deserializeUser()");
done(err, user);
});
});
The global error handler (installed at the end of the Express stack):
var errorHandler = function(err, req, res, next) {
console.log("Error caught by Express error handler")
console.log(err);
res.status(500);
res.render('error', { error: err });
}
app.use(errorHandler);
I think this is probably related to this question, but I'm specifically trying to handle the case when the connection is completely lost (because the database is down). Suggestions?
When running tests that utilize domains for error handling, Mocha still appears to be throwing an error even if a domain handler inside a library should have caught the error. If I execute the code outside of Mocha, it functions correctly leading me to believe the problem is Mocha.
Example:
foo.js
module.exports = function(done) {
var domain = require("domain");
var d = domain.create();
d.on("error", function() {
done();
});
d.run(function() {
throw new Error("foo");
});
}
test.js - Error thrown inside foo.js is not being caught by the domain.
describe("test", function() {
it("should succeed", function(done) {
var foo = require("./foo.js");
foo(function() {
console.log("done");
done();
});
});
});
result : error thrown
script.js - error is being properly caught by the domain and bubbled up.
var foo = require("./foo.js");
foo(function() {
console.log("done");
});
result : done
As you can see above, if I node straight to script.js it functions as desired, the error is caught by the domain handler and the code continues. If I run the same block of code inside a Mocha test, the error halts the test and a failure is given. I believe this is because the error is being sent on an uncaughtException handler, or something like it. The other complication is that it works properly in Mocha, if I have a process.nextTick() around the function call, leading me to believe that Mocha is only unable to handle synchronous errors, but works just fine with async errors.
There is some talk of this problem here: https://groups.google.com/forum/#!msg/nodejs/n-W9BSfxCjI/SElI1DJ_6u0J and https://github.com/joyent/node/issues/4375 .
The confusion I have is that all of this discussion seems to state the problem has been resolved months ago. Anyone know of either a simple work-around for the issue, or a why I'm not seeing a bug fixed which other people seem to believe is fixed at this point in time.
I am running node v0.10.18 and Mocha 1.13.0 on CentOS 6.3 Vagrant VirtualBox on Windows 7.
Found the problem. NodeJS domains catch synchronous errors but the event continues to bubble to a try/catch. If you wrap a domain.run() in a try/catch then the domain error handler AND the catch will be executed.
Thus, it seems the best practice is to use process.nextTick inside all domain.run(). This is shown in the docs example, but isn't expressed as explicitly as I would prefer.
Example:
d.run(function() {
process.nextTick(function() {
// do stuff
});
});
In this case, the flaw is not in Mocha.
Proof of NodeJS domains not catching synchronous errors in try/catch: https://gist.github.com/owenallenaz/7141699
nodejs domains do definitely catch synchronous errors
See this simple test case
var domain = require("domain");
var d = domain.create();
d.on("error", function() {
console.log("domain caught");
});
d.run(function() {
throw new Error("foo");
});
// result: domain caught
EDIT: Since writing this answer I have written a blog post describing what is going on with domains and try catch and whether you can use domains as a wholesale replacement for try catch. It summarises most of what has been discussed here.
http://www.lighthouselogic.com/node-domains-as-a-replacement-for-try-catch/
ORIGINAL ANSWER:
Actually there is a problem with Mocha.
I wrote the following test function:
function error(callback){
var d = domain.create().on('error', function(err){
console.log("Caught Error in Domain Handler")
return callback(err);
});
d.enter();
throw new Error("TestError");
d.exit();
}
Then I wrote a simple test without mocha:
error(function(err){
if(err)
{
console.log("Error was returned");
}else
{
console.log("Error was not returned")
}
})
The output I received was:
Caught Error in Domain Handler
Error was returned
When I tested using Mocha:
describe('Domain Tests', function(){
it('Should return an error when testing', function(done){
error(function(err){
if(err)
{
console.log("Error was returned");
}else
{
console.log("Error was not returned")
}
return done();
})
});
});
I received the following output:
․
0 passing (4ms)
1 failing
1) Domain Tests Should return an error when testing:
Error: TestError
at error (/Users/bensudbury/Documents/node_projects/testMochaDomains/test.js:9:11)
at Context.<anonymous> (/Users/bensudbury/Documents/node_projects/testMochaDomains/testMocha.js:6:3)
at Test.Runnable.run (/usr/local/share/npm/lib/node_modules/mocha/lib/runnable.js:194:15)
at Runner.runTest (/usr/local/share/npm/lib/node_modules/mocha/lib/runner.js:358:10)
at /usr/local/share/npm/lib/node_modules/mocha/lib/runner.js:404:12
at next (/usr/local/share/npm/lib/node_modules/mocha/lib/runner.js:284:14)
at /usr/local/share/npm/lib/node_modules/mocha/lib/runner.js:293:7
at next (/usr/local/share/npm/lib/node_modules/mocha/lib/runner.js:237:23)
at Object._onImmediate (/usr/local/share/npm/lib/node_modules/mocha/lib/runner.js:261:5)
at processImmediate [as _immediateCallback] (timers.js:330:15)
As you can see: the domain error handler was short circuited.
This problem seems to be related to the following issues:
https://github.com/visionmedia/mocha/issues/513
While the Node issue has been closed, the issue in mocha is still open.
The workaround that was suggested at: https://gist.github.com/mcollina/4443963 didn't resolve the issue in this case.
I dug through the code of Mocha and found that the problem occurs because mocha wraps the tests in a try catch block. This means that the exception is caught and never sent to the uncaughtException or _fatalException handler depending upon the version of node that you are using.
Your workaround is good, but nodejs domains do definitely catch synchronous errors so I wouldn't change your code but instead change your test. Your new test should look like:
describe("test", function() {
it("should succeed", function(done) {
process.nextTick(function(){
var foo = require("./foo.js");
foo(function() {
console.log("done");
done();
});
})
});
});
I haven't tested this code, but similar code for my example works properly:
it('Should return an error when testing', function(done){
process.nextTick(function(){
error(function(err){
if(err)
{
console.log("Error was returned");
}else
{
console.log("Error was not returned")
}
return done();
});
})
});
I have added a comment to the end of the issue in Mocha to see if it can be resolved:
https://github.com/visionmedia/mocha/issues/513
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.