I'm confused about error handling with promises. The answer might be obvious, but I'm not getting it.
I have the following example code:
var test = async function(){
throw new Error('Just another error')
}
try {
test().then()
}
catch(err){
alert('error: ' + err.toString())
}
In my browser I don't get an alert and Uncaught (in promise) Error
in the console. Why is that? Shouldn't the try..catch block handle the error?
I can see two possible aspects to your question:
The error being thrown in test
is in the synchronous (not asynchronous) part of test
. Why is it a promise rejection rather than a synchronous exception?
The promise from test()
is being rejected, why doesn't catch
catch that rejection?
Because even if an async
function throws during the synchronous portion of its work, that just rejects the promise it returns, it doesn't raise a synchronous error. It's just a design decision made during the design of async
functions, and a smart one — if it were a synchronous error when throwing in the synchronous part of the function but a promise rejection after that, it would be chaotic and hard to understand. So it's simple: throwing in an async
function always rejects its promise.
(This is consistent with how the promise constructor treats the executor callback you pass into it. When you do new Promise((resolve, reject) => /*...*/})
, the promise constructor calls your function synchronously, but if you throw during the call, it uses what you throw to reject the promise rather than allowing it to continue as a synchronous exception.)
catch
block?Because you're not using await
. Promise rejections are only exceptions when you are await
ing the promise. If you use the promise methods then
/catch
/finally
to attach handlers, rejection is handled by calling the rejection handler, not by the exception mechanism.
So either use promise methods to attach fulfillment and rejection handlers:
test()
.then(result => {
// ...use `result` here...
})
.catch(error => {
// ...handle/report error here...
});
Or use await
in an async
function (or at the top level of a module if you have top-level await
in your enviroment):
// In an `async` function (or the top level of a module in cutting-edge environments)
try {
const result = await test();
// ...use `result` here...
}
catch(err){
// ...handle/report error here...
}