Node错误处理笔记之挖坑系列教程

2020-06-17 06:34:12易采站长站整理

04 小结

说了这么多,就做个小小总结吧  以上关系网可以概括为如图:

个人见解,实际处理中基于几点准则:

1、对于需要具象化的错误信息,也就是我们需要知道具体是哪一块的错误,并且在错误发生时即进行个性化处理。这一类型的错误,在程序中执行时要对可能会出错的函数进行 catch,方式有多种:  try … catch(同步);  或 通过 node 形式的标准错误回调 (err) => {…}(要求所调用的方法,支持该种写法);  或 监听 error 事件 .on(‘error’, err => {…})(要求所调用的对象继承自 EventEmitter 实例,并内部发生错误时,会 emit(‘error’))。

2、promise 形式的错误,可在 promise 实例的末尾再引入 .catch,可捕获该实例所有 then 中抛出的异常;另外 async 的引入也允许了我们可以如同步操作一样捕获错误。

3、但有时候程序的运行,不可能针对所有的函数操作等都去 try … catch,也不能保证程序运行一定就无 bug,但必须要能够把这些异常都捕获并上报。因此 process 的两个大 boss:  unhandledRejection & uncaughtException,是必须引入的,在程序最外层引入,且越靠前越好。此外针对 unhandledRejection,为防止说把不必要的 rejection 上报,可以在收到事件时,先把被 reject 的 promise 和 error 存储起来,设置时间 maxTimeout ,超过 maxTimeout 仍未收到 rejectionHandled 的 promise 事件,再上报。

koa 项目为例:

05 源码解读

下图为 node 中对于 process 的初始化等系列流程:

node.cc 其实是 node 运行主要的文件,其中定义了三个重载函数 Start,调用顺序为 3 → 2 → 1,每个函数参数不同处理不同的逻辑;

isolate->AddMessageListener 的监听事件 OnMessage 会在 js 运行发生错误时触发,嗯,是的,只有 error 才会传递 ;这很好的解释了为什么 process 监听 uncaughtException 就可以监听到所有的抛出的非 promise 异常;

OnMessage 调用了 FatalException 函数,FatalException 引用 process.fatalException 并传入 error (env 是 env.h 中声明的 Environment 类实例,fatalexceptionstring 也是其中定义的,返回值为 ‘fatalException’);  以下为 FatalException 函数的部分内容。

在调用 fatalException 函数前,先调用 v8::TryCatch::setVerbose 把 verbose 设置为 false,则运行时抛出的异常就不会再触发 FatalException ;在捕获到运行错误后,把 exitcode 设为 7,并返回;这就解释了为什么在 uncaughtException 时抛出的异常不会再重新触发回调,要知道 EventEmitter 可没帮你做这样的事情。