Here I have a code that likes a post on my blog website, it has three phases. 1- adding liked post to the users list of liked posts, 2- adding the like to the post itself and 3- creating a notification. But I dont want 1 and 3 to work if 2 has an error.
module.exports.like = (req, res) => {
try{
const userReq = {body: {set: {likedPosts: req.body.post_id}, unset: {}}, params: {userId: req.body.user_id}};
const postReq = {body: {set: {likedPeople: req.body.user_id}, unset: {}}, params: {postId: req.body.post_id}};
const notifReq = {body: {to: req.body.poster_id, fromPost: req.body.post_id, content: "*title* Baslikli postunuz *magnitude* begeni aldi!", magnitude: 1, title: "Icerigin begenildi", img: "https://images.emojiterra.com/google/android-10/512px/1f44d.png", kind: "postLikes"}}
console.log(notifReq);
userController.pushUser(userReq, {send: _ => {console.log(_)}, status: _ => {}});
postController.pushPost(postReq, {send: _ => {console.log(_)}, status: _ => {}});
notiController.newNotif(notifReq, {send: _ => {console.log(_)}, status: _ => {}});
res.status(200).send("Success!");
}catch(err){
console.log("Wrong parameters")
res.status(500).send(err);
}
}
Is there a good structure to do this, I might be doing it all wrong so I am open for suggestions.
Example case is that I check if the post has been liked by that person before, so if that person already liked it then I send an error, So in this case I would like this whole operation to shut down with an error and revert any changes.
CodePudding user response:
From what I understand, you want other controller code to run based on how postController.pushPost
runs.
Promises (or even old style callbacks) can be a good answer in this case. If you can promisify postController.pushPost
(considering that it isn't already returning a Promise or isn't already an async
function), then this will be extremely easy.
You can do something like:
const promisifiedPushPost = (...originalArgs) => {
return new Promise((resolve, reject) => {
try {
// considering the pushPost operation is synchronous
pushController.pushPost(originalArgs);
resolve();
}
catch (err) {
reject(err);
}
});
};
module.exports.like = (req, res) => {
.
.
.
promisifiedPushPost (postReq, {send: _ => {console.log(_)}, status: _ => {}})
.then(() => {
userController.pushUser(userReq, {send: _ => {console.log(_)}, status: _ => {}});
notiController.newNotif(notifReq, {send: _ => {console.log(_)}, status: _ => {}});
res.status(200).send("Success!");
})
.catch((err) => {
console.log("Wrong parameters")
res.status(500).send(err);
});
}
CodePudding user response:
Any rollback logic you add in your application wont be fool proof since there is always the case of application going down itself after executing 1. What you are looking for is rollbacks on database layer. These transactions allow multiple operations to pass or fail atomically and database will guarantee that the rollback happens in case of any failure.
If you are using mongo: https://www.mongodb.com/docs/manual/core/transactions/