對錯誤進行分類,理解錯誤是如何產生的,以及錯誤發生後怎麼定位解決,這在構建一個穩定運行的程序過程當中會常常遇到。總結一下,以便有更清晰的認知。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的論述很詳細,此處不在贅述。