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));
Inside the promise, the catch() method will catch the error caused by the throw statement and reject() . If an error occurs and you don't have the catch() method, the JavaScript engine issues a runtime error and stops the program.
You cannot use try-catch statements to handle exceptions thrown asynchronously, as the function has "returned" before any exception is thrown. You should instead use the promise. then and promise. catch methods, which represent the asynchronous equivalent of the try-catch statement.
It resolves once all promises in the array resolve, or reject as soon as one of them rejects. In other words, it either resolves with an array of all resolved values, or rejects with a single error.
As we can see in the output above, even though the promise2 function throws an error, the Promise. all() method does not get rejected, and the browser throws an unhandled error.
TL;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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With