1.ErrorJS中的Error对象。它包含错误的具体信息,包括名称、消息、错误堆栈等。可以通过newError方式创建一个实例,或者调用Error.captureStackTrace将stack错误堆栈信息添加到已有的对象中,然后抛出。2.抛出错误的几种方式ThrowJavascript抛出异常,通过throw方法抛出,不一定都是Error的实例,但是通过nodeJs或者js运行时出现的错误,都是以EventEmitterNodejs的形式进行的错误回调,一个Error的实例,大多数流和异步事件都派生自EventEmitter类||instance,比如fs、process、stream等程序运行过程中抛出的ProcessException,或者底层库抛出的异常,或者运行过程中出现的一些SyntaxError。适用于所有环境缺点:只对同步异常有效观察者模式发布/订阅,通过.on('error',...)||.addEventlistener('error',...)用于注册订阅者,.emit()用于发布事件,但是会有最大maxListener限制,可以更改。源码我就不展示了,很简单,自己去找吧。比如koa的app是基于EventEmitter的扩展,所以可以通过errorclassKoaextendsEventEmitter{...}letapp=newKoa()app.emit('error',..)app.on('error',...)ProcessProcess对象也是EventEmitter的一个实例。可以通过下面两个事件来监听errorrunhandledRejection的回调promise报错。可以监听这个事件catch,但是要注意,promise的rejectioncaught是不知道什么时候发生的,所以实际上这个信息可能是在unhandledRejection事件触发后才被捕获,对应rejectionHandled事件监听,如下:process.on('rejectionHandled',p=>{console.log('已经处理')})process.on('unhandledRejection',(reason,p)=>{console.log('Wenthere')})lettest=newPromise((resolve,reject)=>{leterr=newError('Justforatest')err.name='TestError'reject(err)})setTimeout(()=>{test.catch(err=>{console.log('Excamplework!')console.log(err)})},10000)//打印信息的顺序是://到这里//已经处理//工作实例!//{TestError:Justforatest//....(stackmessagehere)}(接上)uncaughtException其余的js发生在运行过程中||抛出的未捕获错误可以通过监听这个事件来解决,如果不监听这个事件,当异常发生时,会直接导致程序崩溃但是不推荐这种catch方式,程序运行时的错误应该抛出,如果所有的错误都被捕获了,那程序是不是好像没有bug但是打印错误日志的时候需要捕获并上报日志,但是上报之后还需要继续抛错throw,uncaughtException回调中抛出的异常不会再次被捕获,而是以非零状态码退出//PromiseRejectionprocess.on('unhandledRejection',err=>{process.nextTick(()=>{throwerr}))})//Ultimatebossprocess.on('uncaughtException',err=>{...})};4.总结以上用一张图总结一下:5.源码解读,补充之前没有完成的内容。下图是节点node.cc中进程的初始化等一系列过程,其实就是节点运行的主文件,里面定义了三个重载函数Start,调用顺序为3→2→1,每个函数参数处理不同逻辑;isolate->AddMessageListener的监听事件OnMessage会在js运行出错时触发,嗯,是的,只会传error;这很好地解释了为什么进程监听uncaughtException来监听所有抛出的非承诺异常;OnMessage调用FatalException函数,FatalException引用process._fatalException并传入error(env是env.h中声明的Environment类实例,里面也定义了fatal_exception_string,返回值为'_fatalException');以下是FatalException函数的一部分//'_fatalException'Local
