node異常總結

引言

對錯誤進行分類,理解錯誤是如何產生的,以及錯誤發生後怎麼定位解決,這在構建一個穩定運行的程序過程當中會常常遇到。總結一下,以便有更清晰的認知。node

異常分類

顯式異常

function validateName(name) {
    if(!name){
        throw new Error('name is required');
    }
}
try {
    validateName();
}catch (err){
    console.log(err.message,err.stack);
}

說明 有如下幾點須要注意es6

  • 通常用於同步方法,或者異步執行前,不然沒法捕獲異常,process直接exit。
  • 拋出的錯誤通常都是繼承於Error。使用簡單的字符串例如(throw 'error happen')沒法得到調試堆棧信息。
  • 不要在內置的node方法中拋出異常,沒有意義,由於在node中回調函數第一個參數就是錯誤對象,能夠直接處理。

隱藏的異常

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

問題debug

比較low的方法就是console或者打日誌,這個在開發中不用,打日誌通常是用來記錄查看線上問題;開發中通常都是斷點調試,重點分析下。websocket

調試方式一

Node.js 6.3如下,使用老的方式話,node-inspect做爲模塊須要單獨安裝,其做用經過websocket的方式充當一個鏈接通道,負責dev tool和node中運行程序產生的debug信息進行通訊。app

node-inspector & ;node-debug app.js
出現下圖所示就表明成功了。
node-debug1-gcydom

調試方式二

node6.3+中, node --inspect app.js ,使用前開啓chrome的Node debugging選項,出現下面效果標識就成功了。
node-debug2-gcy

說明 上述兩種調試方式,我不多用,通常我都是用webstrome來調試,經過調整Node Interpreter的版原本使用相應的調試方式,原理和上面是同樣的,只是調試形式上變化了下。

7以上我一般都是用 --inspect的方式,不然會提示你'node --debug is deprecated',可是用老方式也沒什麼問題。區別其實就是獲取debug信息的通訊協議方式不一樣,新的方式使用的是Chrome Debugging Protocol,而老的是 V8 Debugging Protoco。

總結

上面我只是總結了通用的異常狀況,其實還有一些特殊的使用方式,例如throw在generator當中的使用,以及promise中能夠直接拋出異常,都不是我上面所說的通常狀況,不在列舉,
由於阮老師關於這兩個api的論述很詳細,此處不在贅述。

相關文章
相關標籤/搜索