I'm creating an API using Restify and Mongoose, and I'm completely new to both. I can't seem to figure out the proper way to handle errors in Mongoose / Node.
As of now, I'm trying to do something like this:
Submission.findById(req.params.submission_id, function(err, data) {
if (err)
return next(err);
res.send(data);
});
I'm attempting to call a GET on this (for a user that not exist). And rather than sending back a simple error message, it causes my entire node application to fail. I'm a bit confused on the user of return next(err) and what that exactly should do.
Any help is greatly appreciated.
A findById query that doesn't find a match isn't an error at the Mongoose level, so you if you want it treated that way you have to do it yourself:
Submission.findById(req.params.submission_id, function(err, data) {
if (err)
return next(err);
else if (!data)
return next(new Error("User not found"));
res.send(data);
});
Related
how can I catch an error in NodeJS or create own error code and send it to the frontend to inform the user?
In the following code I am looking into the database result if there were any data deleted and try to send an error code. How can I send the error code to my react frontend? Maybe using response.json("Not deleted any user"). Tried it already out.
How can I prevent my server from crashing? If the sql is not correcting because there was no id send to delete it is crashing.
Thanks for the answers for this two cases.
db.getConnection((err, connection) => {
if (err) throw err;
connection.query(
"DELETE FROM users where users_id = ?",
[2],
(err, rows) => {
connection.release();
if (rows.affectedRows == 0) {
throw err;
}
if (err) throw err;
if (!err) {
res.redirect("/");
} else {
console.log(err);
}
console.log("Daten gelöscht", rows.affectedRows);
}
);
});
You should use a try, catch block. If you want to throw a custom exception, you can do something like
throw new NotFoundException("Record with the given id Not Found...!!!"):
I use it in nestjs I am not fully sure that this will work for you but you can try :)
Irrespective of the type of database, I can't get a clear picture of best way of handling db errors without crashing the application.
e.g connecting with sql
pool.getConnection(function(err, connection) {
if (err) {
throw err
}
connection.execute('select * ...' , values, function(err, result) {
if (err) {
throw err;
}
});
});
In both cases above I am throwing errors which causes node server to crash.
I want to register the error and respond to the request in a most elegant fashion. Can anyone point in the right direction ?
When you are throwing an error, someone needs to catch them. If you don't catch them anywhere in your code, it will cause the program to crush.
So basically what you need to do is to wrap the call to your functions with try/catch, and in case you catch- log it and return an apporopriate response to the requester.
Something like:
try {
pool.getConnection(function(err, connection) {
if (err) {
throw err
}
connection.execute('select * ...' , values, function(err, result) {
if (err) {
throw err;
}
});
});
} catch (error) {
log(error);
res.status(500).body("failed to get ... " + err).send();
}
I also recommend reading this blog post, has good explanation about the subject
I am using NodeJS and Mongoose for an application that has users. And I have a large number of actions the server does on a particular user, depending on the request.
That means, I have this particular code fragment appearing in a lot of functions:
User.findOne({'email':req.user.email}, function (err, user) {
if (err) {
console.log('err');
res.send('Error');
}
if(!user){
console.log('err');
res.send('Error');
}
// do something with returned user
user.data = ....
...
user.save(function(err) {
if(err) {
console.log('err');
res.send('Error');
}
else {
console.log('success');
res.send('Success');
}
}
As you can see, there is a lot of code that replicates. The code that changes is the part 'do something with returned user'. Almost everything else (error messages, etc.) remains same.
So, how can I extract this part out? Since this is working on callback mechanism, is there a certain way to achieve this?
One way is to use Promises. It would involve finding a way to convert the Mongooose api to return Promises instead of using callbacks. After that, you could create code that would follow the lines of
User.findOne(...)
.then((user) => {
// do something with the returned user
return user.save();
}).then(() => {
console.log('success');
res.send('Success');
}).catch(() => {
console.log('err');
res.send('Error');
});
Promises resemble traditional synchronous coding where you can propagate errors akin to try-catch block and thus needing only one error handling location. This way you wouldn't have to replicate the console.log('err'); res.send('Error'); lines in multiple places.
You can read an introduction to Promises for example in "Promises - A Gentle Introduction". For the part on converting Mongoose to Promises there may be an existing module for this, or another approach that APIs use is to not give callback function as the last argument and then a Promise is returned instead. Unfortunately, I don't have exact knowledge in this particular Mongoose API.
I'm learning MEAN stack with an awesome tutorial online. In it, there is a section about preloading objects by id using express's param().
router.param('post', function(req, res, next, id) {
var query = Post.findById(id);
query.exec(function (err, post){
if (err) { return next(err); }
if (!post) { return next(new Error('can\'t find post')); }
req.post = post;
return next();
});
});
My question are:
Where can I find the API documentation on the exec() function? Is it a Mongoose function? How can I tell if it's a Mongoose function or JS or express function?
What's the purpose of final return next() here? Is it necessary in the exec() function to have return next()? What would happen if that line is absent? I have read that next() is for the next middleware, but in other functions from the tutorial, like below, there is no final next() or return next(). What's the difference between next() and return next() anyways?
router.post('/posts', function(req, res, next) {
var post = new Post(req.body);
post.save(function(err, post){
if(err){ return next(err); }
res.json(post);
});
});
Thanks.
First of all please read document of every library you used, if you read just document of mongoose you figure out what is the exec() !
Ok now we can focus on the point
Q1: The exec() is mongoose function. if you being stuck in this situation which you can't figure out what's going on in code, please check this out.
this web app can help you when you need some info about functions (methods) , properties or ... (work perfectly in offline times).
Q2: Please read this question (By the way i think your last question is duplicated)
MEAN is using express.
next() tells the express server to go to invoke the next middleware.
http://expressjs.com/guide/using-middleware.html
The exec is not expressjs by the way.
Hi i am developing nodejs application. I am inserting data to mongodb but my page always in 'loading' mode. But strange thing is my data inserted to mongodb immediately but page load not stopping. My code is shown below:
app.post('/Management/Post/New',function(req, res){
new Post({
title:req.body.post.title,
body:req.body.post.body,
keywords:req.body.post.keywords
}).save(function (err, docs){
if(err) {
return res.render(__dirname + "/views/createpost", {
title: 'Yeni Gönderi Oluştur',
stylesheet: 'postcreate',
error: 'Gönderi oluşturulurken bir hata ile karşılaşıldı'
});
}
console.log('Gönderi oluşturuldu');
});
});
Have no idea.
You only send a response when there is an error. If there's no error, you server never sends anything back: that's why the page seems to always be loading.
You need to send a response when you have no error, like this:
.save(function (err, docs){
if(err) { // Executed when there was an error with Mongo
return res.render(...);
} else { // Executed when everything is fine
return res.render(...);
}
});
You aren't handling the success scenario except for a console.log. You need a res.render() or res.redirect() on success, not just error