Use Domain to Handle Nodejs Error

最近常常因為追推才開始寫文,這應該算是件好事吧!? :p

剛好都是提到NodeJS中處理Error的問題,就一起看一看,然後發覺其實也蠻相關的,因為他們都不約而同提到Domain,所以順便在這邊做個註記,可以開始試著用domain來簡化在nodejs中處理錯誤的問題。

首先是官方發出的公告:

在現有的http module之中有memory leak的問題,nodejs團隊已經針對問題在v0.8.20的版本中進行修正了,不過遵循著等價交換的原則(啥),會產生更多的hangup的錯誤,當然你也必須在程式中去處理這個問題。

當然,處理錯誤也不是什麼神奇的東西(除非你本來沒在做這件事 XDD 不過[有人提到](http://clock.co.uk/tech-blogs/preventing-http-raise-hangup-error-on-destroyed-socket-write-from-cr ashing-your-nodejs-server)可以利用domain來處理。

JS中的錯誤處理一直沒有一種統一的作法,再加上JS非對稱處理的特性,會產生與其他程式語言不太相同的情況。然後就有位熱
血大大特別寫了篇文章來說明在NodeJS之中,對於錯誤處理的幾種方式。

詳細的內容,大家可以直接看作者的原文,我在這邊只會概略提過。主要可以分成四種方式

  1. Return Error
  2. Throw Exception
  3. Callback
  4. Error Event

方法1在JS應該比較少人使用,所以主要討論放在2,3,4上面,不過無論是哪一種,你都可以利用Domain更有效來處理錯誤:

使用domain.run()(類似try catch的用法,包含整段程式區段)或domain.bind()(綁定特定的函式)在Exception之中,可以解決Exception互相影響的問題(如果你的try catch是多層的話,當最底層的例外被丟出的時候,全部都會被觸發)。

Callback的錯誤處理,一樣可以利用Domain來讓同一個Error handler來處理,而且也可以透過domain.intercept()讓來簡化callback的程式邏輯(因為intercept會自動處理callback的error - 預設是第一個參數),所以就可以變成這樣:

//Old way
test('a', 'b', function(err, data) {  
    if (!err) {
        test(data, 'c', function(err, data) {
            // keep doing
        });
    }
});

//domain
domain.on('error', function(e) {  
    // handle error
});
test('a', 'b', domain.intercept(function(data) {  
    test(data, 'c', domain.intercept(function(data) {
        // keep doing
    });
});

Event就更方便了,因為domain會自動監聽error event,所以直接用domain.run()domain.add(EVENT_OBJ)都可以,然後只要emitter.emit('error', new Error(SOME ERROR)),實作domain.on('error')就可以了。

詳細的部份&範例程式都可以直接到作者原文那邊看,大推!

PS:前幾天又看到一個新個module - trycatch,說不定可以拿來試試,整合domain, long stack traces, color, format,除錯上看來會更方便一些 ;p

Ferrari Lee

Read more posts by this author.

Subscribe to Ferrari != Ferrari

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!