Reputation: 31
My code resembles this:
router.post("/", (req, res, next) => {
foo()
.then((result) => {
res.send(result)
})
.catch((error) => {
cosnole.log(error)
})
//I only want the bar() function and everything below it to run if the first promise is rejected and the first .catch function ran
bar()
.then((data) => {
res.send(data)
})
.catch((error) => {
console.log(error)
})
})
I'd like to only run the bar() function and the .then .catch functions after it only if the first promise is rejected and the .catch function fires off.
I've tried this:
router.post("/", (req, res, next) => {
rejected = false
foo()
.then((result) => {
res.send(result)
})
.catch((error) => {
rejected = true
console.log(error)
})
if(rejected == true)
bar()
.then((data) => {
res.send(data)
})
.catch((error) => {
console.log(error)
})
})
but the bar() function never gets executed when the first foo() function's error is caught and the promise is rejected.
Upvotes: 2
Views: 551
Reputation: 4393
Try returning bar to chain your promise.
router.post("/", (req, res, next) => {
foo()
.then((result) => {
res.send(result)
})
.catch((error) => {
console.log(error);
return bar;
})
.then((data) => {
res.send(data);
})
.catch((error) => {
console.log(error)
});
});
----------------- EDIT -----------------
Here's a fully testable copy of an ExpressJS sample with your problem:
const express = require("express");
const app = express();
const port = process.env.PORT || 4000;
app.get("/", function(req, res) {
foo = new Promise(function(resolve, reject) {
// resolve("resolved"); // Uncomment for resolve
reject("rejected");
});
bar = new Promise(function(resolve, reject) {
resolve("myData");
});
foo.then((result) => {
res.send(result);
}).catch((error) => {
console.log(error);
return bar;
}).then((data) => {
res.send(data);
});
});
app.listen(port, function () {
console.log("Listening on port: " + port);
});
Upvotes: -1
Reputation: 664920
As others mentioned, you just need to move the code inside that catch
handler.
However, you will probably want to simplify and correct your code to
router.post("/", (req, res, next) => {
foo().catch(bar).then(result => {
res.send(result);
, error => {
console.error(error);
res.sendStatus(500); // or next(error) or whatever
});
})
If you want to log errors from foo
even when they're handled by bar
, you might need
foo().catch(error => {
console.log(error, "(handled by bar)");
return bar();
}).…
Upvotes: 3
Reputation: 328
Given the asynchronous nature of your code, if (rejected==true)
will always be false
, because that code is executed before the first then
or catch
.
You can:
foo()
.then((result) => {
res.send(result)
})
.catch((error) => {
console.log(error)
bar()
.then((data) => {
res.send(data)
})
.catch((error) => {
console.log(error)
})
})
rejected = false
foo()
.then((result) => {
res.send(result)
})
.catch((error) => {
console.log(error)
rejected = true
})
.then(() => {
if(rejected) {
bar()
.then((data) => {
res.send(data)
})
.catch((error) => {
console.log(error)
})
}
})
Upvotes: 0
Reputation: 62238
Move the call to inside the catch.
router.post("/", (req, res, next) => {
foo()
.then((result) => {
res.send(result)
})
.catch((error) => {
cosnole.log(error);
return bar()
.then((data) => {
res.send(data)
})
.catch((error) => {
console.log(error)
});
});
});
Upvotes: 4
Reputation: 4488
I/O calls happens asynchronously, so your if
code gets running before res.send() return any response. There are several ways to handle this scenario, here is another way using asyn/await
in order to write code which looks like synchronous:
router.post("/", async (req, res, next) => {
rejected = false
try {
await foo()
.then((result) => {
res.send(result)
})
} catch {
rejected = true
console.log(error)
}
if(rejected == true)
bar()
.then((data) => {
res.send(data)
})
.catch((error) => {
console.log(error)
})
})
Upvotes: 0