Reputation: 40104
I have a function that calls a promise. On success or failure I would like to return some data beyond what the promise returns.
I thought this might work:
function foo() {
const extra = 'bar'
return thepromise().then((res) => {
return {
result: res,
data: extra
}
}, (err) => {
// this will not happen if an error is thrown in the called promise
return {
result: res,
data: extra
}
})
}
foo().then((res) => { }, (err) => { // error result ends up here })
However this does not work. if an error is thrown in the thepromise
it will not call the catch block but instead the catch block of foo()
.
What is the proper way to handle this? I am successful with a try/catch block but I am not sure this is the best approach:
function foo() {
const extra = 'bar'
return new Promise((resolve, reject) => {
try {
return thepromise(p)
} catch (e) {
reject(e)
}
})
.then(function(res) {
return {
result: res,
data: extra,
status: 'success'
}
}, function(err) {
return {
result: err,
data: extra
status: 'error'
}
})
}
Upvotes: 0
Views: 2891
Reputation: 78840
If you're willing to entertain extensions to Promises, bluebird
has a try method that does just what you need:
import Promise from 'bluebird';
// ...
return Promise
.try(thepromise)
.then(res => ({
result: res,
data: extra
})
.catch(err => ({
result: res,
data: extra
});
Upvotes: 0
Reputation: 1
The error is considered handled at .catch()
, which would return a resolved promise to chained .then()
. You can throw
the error to the next .catch()
function foo() {
const extra = 'bar'
return thepromise().then((res) => {
return {
result: res,
data: extra
}
}, (err) => {
throw new Error(JSON.stringify({
result: err || "no rejection reason provided",
data: extra
}))
})
}
var thepromise = () => Promise.reject();
foo().then(data => console.log("fulfilled", data))
.catch(err => console.log("catch", JSON.parse(err.message)))
Upvotes: 0
Reputation: 179086
Any function designed to return a promise should not be throwing any sort of exception or error.
If it does, it should be considered buggy.
To fix a buggy method, instead of throwing an exception, reject the returned promise.
Sometimes you're not in a position to fix the underlying bug, such as when you're using someone else's API. If this is the case, the first and most important thing to do is report the bug to the original authors so that the underlying issue can be fixed.
After reporting the issue, you can wrap the buggy method in a simple utility to fix the issue:
function fixBrokenPromise(promise/*, args...*/) {
var args = Array.prototype.slice.call(arguments, 1),
ret;
try {
ret = promise.apply(null, args);
} catch (ex) {
ret = Promise.reject(ex);
}
return ret;
}
This can be called as:
fixBrokenPromise(thepromise/*, args you want to pass to thepromise */)
.then(...resolve...,
...reject...);
Upvotes: 4