在顶层正确处理异步函数的异常
Properly handling exceptions from async functions at the top level
我无法理解在不触发 Node UnhandledPromiseRejectionWarning
的情况下处理异步函数异常的正确方法(因为这似乎表明我做错了什么)。
通常,在非异步代码中,未处理的异常会一直冒泡到顶部并最终打印到控制台。导致异常的代码一直停止返回堆栈。
假设我有以下代码:
test1().catch((e) => { throw e; });
console.log('got here top-level'); // This will print
async function test1() {
let test2Result = await test2();
console.log('got here test 1'); // This won't print
return test2Result;
}
async function test2() {
throw new Error('something failed here');
}
我希望这会做我想做的。在最顶层,它从异步函数中捕获异常并重新抛出(但现在在任何异步代码或 Promises 之外)。它应该仍然有原始的堆栈跟踪,这样我就可以找到问题所在。快乐的日子,对吧?但是不,这仍然导致 UnhandledPromiseRejectionWarning
,我不明白为什么。
从 Promises 内部捕获所有未处理的异常的正确方法是什么?
你的误解来自于这个说法...
catches the exception from the async functions and re-throws (but now outside any async code or Promises)
Promise.prototype.catch() 仍然是异步代码。它 return 是一个 Promise,就像 .then()
一样(事实上,.catch(onRejected)
只是 .then(undefined, onRejected)
的别名)。
有趣的是,如果 .catch()
回调不是 return 被拒绝的承诺(例如 Promise.reject()
)或 throw
,它 return 是成功的/ 已解决的承诺。
当你 throw e
在你的 .catch()
中时,return 值是一个被拒绝的 Promise,因为这是未处理/未捕获的,你会得到臭名昭著的 UnhandledPromiseRejectionWarning
。 =22=]
为避免这种情况,只需处理所有可能的承诺拒绝
test1().catch(console.error); // returns a resolved promise
// or
try {
await test1();
} catch (e) {
// consider this handled
}
我通常会这样做:
async function main() {
// do some async stuff here
await someAsyncWork();
}
let cc;
main()
.then( () => {
console.log('success!');
cc = 0 ;
}
.catch( e => {
console.error(e.stack);
cc = 1;
})
.finally( () => process.exit(cc) );
我无法理解在不触发 Node UnhandledPromiseRejectionWarning
的情况下处理异步函数异常的正确方法(因为这似乎表明我做错了什么)。
通常,在非异步代码中,未处理的异常会一直冒泡到顶部并最终打印到控制台。导致异常的代码一直停止返回堆栈。
假设我有以下代码:
test1().catch((e) => { throw e; });
console.log('got here top-level'); // This will print
async function test1() {
let test2Result = await test2();
console.log('got here test 1'); // This won't print
return test2Result;
}
async function test2() {
throw new Error('something failed here');
}
我希望这会做我想做的。在最顶层,它从异步函数中捕获异常并重新抛出(但现在在任何异步代码或 Promises 之外)。它应该仍然有原始的堆栈跟踪,这样我就可以找到问题所在。快乐的日子,对吧?但是不,这仍然导致 UnhandledPromiseRejectionWarning
,我不明白为什么。
从 Promises 内部捕获所有未处理的异常的正确方法是什么?
你的误解来自于这个说法...
catches the exception from the async functions and re-throws (but now outside any async code or Promises)
Promise.prototype.catch() 仍然是异步代码。它 return 是一个 Promise,就像 .then()
一样(事实上,.catch(onRejected)
只是 .then(undefined, onRejected)
的别名)。
有趣的是,如果 .catch()
回调不是 return 被拒绝的承诺(例如 Promise.reject()
)或 throw
,它 return 是成功的/ 已解决的承诺。
当你 throw e
在你的 .catch()
中时,return 值是一个被拒绝的 Promise,因为这是未处理/未捕获的,你会得到臭名昭著的 UnhandledPromiseRejectionWarning
。 =22=]
为避免这种情况,只需处理所有可能的承诺拒绝
test1().catch(console.error); // returns a resolved promise
// or
try {
await test1();
} catch (e) {
// consider this handled
}
我通常会这样做:
async function main() {
// do some async stuff here
await someAsyncWork();
}
let cc;
main()
.then( () => {
console.log('success!');
cc = 0 ;
}
.catch( e => {
console.error(e.stack);
cc = 1;
})
.finally( () => process.exit(cc) );