I stumbled upon some code that looked off to me:
try {
somePromise()
.then(res => console.log(res));
} catch (err) {
console.error(err);
}
If some somePromise()
fails, would this not get caught, and the app would crash? Does this try-catch even do anything?
Should be this, correct?:
somePromise()
.then(res => console.log(res))
.catch(err => console.error(err));
I stumbled upon some code that looked off to me:
try {
somePromise()
.then(res => console.log(res));
} catch (err) {
console.error(err);
}
If some somePromise()
fails, would this not get caught, and the app would crash? Does this try-catch even do anything?
Should be this, correct?:
somePromise()
.then(res => console.log(res))
.catch(err => console.error(err));
Share
Improve this question
edited Apr 30, 2017 at 2:05
atkayla
asked Apr 30, 2017 at 2:04
atkaylaatkayla
8,84917 gold badges85 silver badges142 bronze badges
12
|
Show 7 more comments
2 Answers
Reset to default 19TL;DR - If a function that returns a promise throws an exception before returning the promise then that exception would have to be caught in a regular try-catch block.
Consider this function
function asyncAdd(x,y){
if(x === 2){
throw new Error("good old exception")
}else if(x === 1) {
return Promise.reject("fancy exception")
}
return Promise.resolve(x+y)
}
This would print "Try caught good old exception"
try{
asyncAdd(2,10).then(x =>console.log("result", x)).catch(y => console.error("Promise caught", y));
}catch (e){
console.error("Try caught", e);
}
This would print "Promise caught fancy exception"
try{
asyncAdd(1,10).then(x =>console.log("result", x)).catch(y => console.error("Promise caught", y));
}catch (e){
console.error("Try caught", e);
}
If you're dealing with a rubbish function that could return a Promise or throw an Error, that is truly unfortunate. I would recommend a generic tryCatch
utility like below to deal with the offensive function.
const badFunction = x =>
{ if (x)
return Promise.resolve(x)
else
throw Error('this is a bad function')
}
const tryCatch = (f, ...args) =>
new Promise(r => r(f(...args)))
tryCatch(badFunction, 1)
.then(console.log, console.error)
// 1
tryCatch(badFunction, 0)
.then(console.log, console.error)
// Error: this is a bad function
Fix it if you can
If the rubbish function is under your control to fix, then I would recommending writing it something like this
const goodFunction = x =>
{ if (x)
return Promise.resolve(x)
else
return Promise.reject(Error('this is a good function'))
}
goodFunction(1).then(console.log, console.error)
// 1
goodFunction(0).then(console.log, console.error)
// Error: this is a good function
Uncaught errors in .then
-chained functions
That's not to say that sometimes we still might encounter a situation where you will need to use a function that could throw. For example, if we then
a function that can throw – JSON.parse
in this case - Promises are already equipped to handle this in a convenient way; the thrown Error will be captured inside of a rejected promise
const goodFunction = x =>
Promise.resolve(x)
goodFunction('"abc"')
.then(JSON.parse)
.then(console.log, console.error)
// 'abc'
goodFunction('abc')
.then(JSON.parse)
.then(console.log, console.error)
// 'Unexpected token a in JSON at position 0'
Uncaught errors in Promise executor
If a function throws an error in your Promise executor, don't worry, the error will be contained in an automatically rejected promise -
const okFunction = x =>
new Promise(resolve => resolve(JSON.parse(x)))
okFunction('"abc"').then(console.log, console.error)
// 'abc'
okFunction('abc').then(console.log, console.error)
// Error: Unexpected token a in JSON at position 0
somePromise()
could still throw an error. – Felix Kling Commented Apr 30, 2017 at 2:05somePromise
an error could be thrown before the promise is returned. – Felix Kling Commented Apr 30, 2017 at 2:08