最近在排查项目问题,发现部分日志奇怪丢失,明明外部有try catch 包裹。这里记录一下排查过程及解决方案。
宏任务异常
async function cb() {return new Promise((resolve, reject) => {reject('err') // 只能通过 promise.catch 捕获reject(new Error('err')) // 可以捕获// throw new Error('err') 与上面代码效果相同})}async function foo() {try {cb()// await cb() 加 await 则可以捕获} catch (error) {console.log('myError', error.message)}}foo()
原因:async 函数是 generate 函数的语法糖。根据 await 将函数拆分成几段异步调用链。及await 后面的代码是等到cb 的promise.then 中执行。如果没有 await 就是同步执行。cb 函数的错误没有被捕获。
**
微任务异步异常
async function foo() {try {setTimeout(() => {throw new Error('err')}, 1000)} catch (error) {console.log('myError', error.message)}}foo() // 没有任何错误打印
原因: foo() 函数退出了调用栈(try,catch 也执行完)。之后setTimeout 回调执行,此时没有异常捕获
解决方案
- 在异步函数内部 try catch
- 外部包裹 async await 函数,try catch 捕获(例如 koa 中间件进行异常捕获,不要忘记 await next())
- 监听 process
uncaughtException,unhandledRejection事件
