I am refactoring my promise chaining codes to async/await style. One of the reasons to do that is I want a single catch block to handle to all error situations (as explained here Understanding promise rejection in node.js)
My question is when I hit a sync error, should I call await Promise.reject
or throw error
to bail out the process?
I know either way will work but I prefer throw error
. I already know I got an invalid result why should I await? Using throw to terminate the control flow immediately seems to be a better option.
I am not talking about the promise chain(the whole point of my question), so I don't think the thread JavaScript Promises - reject vs. throw answered my question.
I read the article Error Handling in Node.js I don't think it gives an answer either. But it did say
A given function should deliver operational errors either synchronously (with throw) or asynchronously (with a callback or event emitter), but not both. ... In general, using throw and expecting a caller to use try/catch is pretty rare...
My async function(s) may return Promise.reject. So I am concerned about introducing 2 ways to delivering errors as that article against.
try {
let result = await aysncFunc().
if (!isResultValid(result)) { //isResultValid() is sync function
await Promise.reject('invalid result')
//or throw 'invalid result'
}
... //further processing
}
catch (error) {
...
}
I am refactoring my promise chaining codes to async/await style. One of the reasons to do that is I want a single catch block to handle to all error situations (as explained here Understanding promise rejection in node.js)
My question is when I hit a sync error, should I call await Promise.reject
or throw error
to bail out the process?
I know either way will work but I prefer throw error
. I already know I got an invalid result why should I await? Using throw to terminate the control flow immediately seems to be a better option.
I am not talking about the promise chain(the whole point of my question), so I don't think the thread JavaScript Promises - reject vs. throw answered my question.
I read the article Error Handling in Node.js I don't think it gives an answer either. But it did say
A given function should deliver operational errors either synchronously (with throw) or asynchronously (with a callback or event emitter), but not both. ... In general, using throw and expecting a caller to use try/catch is pretty rare...
My async function(s) may return Promise.reject. So I am concerned about introducing 2 ways to delivering errors as that article against.
try {
let result = await aysncFunc().
if (!isResultValid(result)) { //isResultValid() is sync function
await Promise.reject('invalid result')
//or throw 'invalid result'
}
... //further processing
}
catch (error) {
...
}
Share
Improve this question
edited May 29, 2018 at 7:13
Qiulang
asked May 29, 2018 at 2:42
QiulangQiulang
12.5k20 gold badges96 silver badges153 bronze badges
5
-
1
I know either way will work but I prefer throw error
- well, go forth and do that - but are you sure either way will work? – Jaromanda X Commented May 29, 2018 at 2:44 - "but are you sure either way will work?" I am 99% sure. But that is also one of the reasons I asked my question. – Qiulang Commented May 29, 2018 at 3:01
-
Of course it is 100% works (as in your code block). I prefer to throw error directly +1, anything you throw in the sync code could be caught. It just more elegant and nature.
await Promise.reject()
is redundant, and potentially could cause confusions for some people. – Leo Li Commented May 29, 2018 at 3:15 -
But I think you may hit to a bad direction. Don't use
async/await
just trying to be fashionable. Use it when it is really needed; i.e. async operation, and also useawait Promise.all([...])
if you have two or more independent async operations. – Leo Li Commented May 29, 2018 at 3:19 - Also, another reason for it is performance, but it just marginal in most cases. – Leo Li Commented May 29, 2018 at 3:28
1 Answer
Reset to default 6It's semantically correct to use throw
in promise control flow, this is generally preferable way to bail out of promise chain.
Depending on coding style, await Promise.reject(...)
may be used to differentiate between real errors and expected rejections. Rejected promise with string reason is valid but throw 'invalid result'
is considered style problem that may be addressed with linter rules, because it's conventional to use Error
instances as exceptions.
The reason why it's important is because string exceptions can't be detected with instanceof Error
and don't have message
property, consistent error logging as console.warn(error.message)
will result in obscure undefined
entries.
// ok
class Success extends Error {}
try {
throw new Success('just a friendly notification');
} catch (err) {
if (!(err instanceof Success)) {
console.warn(err.message);
throw err;
}
}
// more or less
const SUCCESS = 'just a friendly notification';
try {
await Promise.reject(SUCCESS);
} catch (err) {
if (err !== SUCCESS)) {
console.warn(err.message);
throw err;
}
}
// not ok
try {
throw 'exception';
} catch (err) {
if (typeof err === 'string') {
console.warn(err);
} else {
console.warn(err.message);
}
throw err;
}
Since invalid result
is actually an error, it's reasonable to make it one:
throw new TypeError('invalid result');
I am not talking about the promise chain(the whole point of my question), so I don't think the thread JavaScript Promises - reject vs. throw answered my question.
async
function is syntactic sugar for promise chain, so all points that are applicable to promises are applicable to async
as well.
There may be cases when throwing an error is not the same as rejecting a promise, but they are specific to other promise implementations like AngularJS $q
and don't affect ES6 promises. Synchronous error in Promise
constructor results in exception, this also isn't applicable to async
.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1742296558a4417240.html
评论列表(0条)