对错误进行分类,理解错误是如何产生的,以及错误发生后怎么定位解决,这在构建一个稳定运行的程序过程当中会常常遇到。总结一下,以便有更清晰的认知。node
function validateName(name) { if(!name){ throw new Error('name is required'); } } try { validateName(); }catch (err){ console.log(err.message,err.stack); }
说明 有如下几点须要注意es6
function getName() { return name; } getName();
说明 隐藏的异常不是由throw触发,而是在运行时发生的,例如上面常见的ReferenceError,这种异常可使用eslint等工具检查出来。web
no-undef:error
var EventEmitter=require('events').EventEmitter; var ee=new EventEmitter(); ee.on('error',function (err) { console.error(err.message,err.stack); console.log("end"); }); ee.emit('error',new Error('no handled event error'));
说明 当EventEmitter实例发生错误时,会触发error事件,若是没有error事件的监听器,默认会打印堆栈,而后退出程序。若是实例比较多,想要统一管理,可使用domain模块管理。例以下面的示例,集中处理connection时发生的异常。chrome
var domain=require('domain'); var http=require('http'); var d=domain.create(); d.run(function () { var server=http.createServer(function (req,res) { d.on('error',function () { res.statusCode=500; res.end('internal server error'); server.close(); setTimeout(process.exit,5000,1); }) response.end('hello world'); }).listen(3000); });
使用域的好处是,能够把各式异常放到一个域的异常处理函数中,且不影响其余的域。在非阻塞式api中,通常都是用domain集中处理异常。想要全局处理,能够按照下面的方式来个统一处理,不推荐。json
var http=require('http'); var server=http.createServer(function (req,res) { response.end("hello world"); }).listen('3000'); process.on('uncaughtException',function (err) { console.log(err); })
uncaughtException是最后一道防线,比较好的作法是记录错误信息,而后重启。api
fs.readFile('./config.json',function (err,buf) { // if(err) throw err; if(err) throw new Error('read file filed');; var config=JSON.parse(buf.toString()); console.log(config); })
说明 上述示例中,若是忽略readFile返回的错误,有可能没法获取buf而抛出异常,因此错误参数仍是须要处理一下。promise
比较low的方法就是console或者打日志,这个在开发中不用,打日志通常是用来记录查看线上问题;开发中通常都是断点调试,重点分析下。websocket
Node.js 6.3如下,使用老的方式话,node-inspect做为模块须要单独安装,其做用经过websocket的方式充当一个链接通道,负责dev tool和node中运行程序产生的debug信息进行通讯。app
node-inspector & ;node-debug app.js
出现下图所示就表明成功了。dom
node6.3+中, node --inspect app.js ,使用前开启chrome的Node debugging选项,出现下面效果标识就成功了。
说明 上述两种调试方式,我不多用,通常我都是用webstrome来调试,经过调整Node Interpreter的版原本使用相应的调试方式,原理和上面是同样的,只是调试形式上变化了下。
7以上我一般都是用 --inspect的方式,不然会提示你'node --debug is deprecated',可是用老方式也没什么问题。区别其实就是获取debug信息的通讯协议方式不一样,新的方式使用的是Chrome Debugging Protocol,而老的是 V8 Debugging Protoco。
上面我只是总结了通用的异常状况,其实还有一些特殊的使用方式,例如throw在generator当中的使用,以及promise中能够直接抛出异常,都不是我上面所说的通常状况,不在列举,
由于阮老师关于这两个api的论述很详细,此处不在赘述。