It'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
.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…