2012-07-22 34 views

回答

12

這對音箱甲板組幻燈片給出了一個簡潔的概述:

快遞中間件代碼的幻燈片:

var createDomain = require('domain').create; 

app.use(function(req, res, next) { 
    var domain = createDomain(); 

    domain.on('error', function(err) { 
    // alternative: next(err) 
    res.statusCode = 500; 
    res.end(err.message + '\n'); 

    domain.dispose(); 
    }); 

    domain.enter(); 
    next(); 
}); 
+4

你測試過了嗎?它不適用於我,並且domain.enter在節點的網站上沒有記錄。 – 2012-07-22 15:12:21

+0

這對我有用。我不知道爲什麼domain.enter沒有記錄。 – 2012-09-11 17:25:27

+3

我應該加我擔心,這段代碼調用domain.enter但沒有相應的domain.exit。似乎可能會泄漏。 – 2012-09-11 17:45:55

5

我有好運氣更換股票

var app = express.createServer(); 

有:

var domainCreate = require('domain').create; 
var app = express.createServer(function (req, res, next) { 
    var domain = domainCreate(); 
    domain.run(next); 
}); 

然後在你的中間件,您可以添加屬性process.domain或添加更多的錯誤處理。

+1

這可能是一個很好的答案,但'express.createServer'已被棄用 – Jess 2013-10-02 01:25:08

+0

如果您沒有針對該域的特定錯誤處理,這是什麼目的? – 2016-01-05 09:07:35

12

更新:下面介紹的方法已在connect-domain NodeJS模塊中實現,該模塊可用於Connect或Express應用程序。

從Express 3開始,express.createServer已棄用,其回調應轉換爲中間件。在中間件中,將請求和結果對象添加到請求域非常重要,這樣它們觸發的錯誤就由域錯誤處理程序處理。

我中間件看起來是這樣的:

var domain = require('domain'); 

app.use(function(req, res, next) { 
    var requestDomain = domain.create(); 
    requestDomain.add(req); 
    requestDomain.add(res); 
    requestDomain.on('error', next); 
    requestDomain.run(next); 
}); 

可避免增加請求和響應請求域,如果你從一個頂級域名內致電http.createServer,但域文檔似乎表明,每個請求域是最佳實踐。

請注意,上面的代碼不會執行任何域清理操作,例如強制處置請求域。我的中間件選擇通過中間件堆棧再次傳遞錯誤,以便稍後通過特定的錯誤處理中間件來處理。因人而異。

+0

這不是防止在第三方庫中拋出的異常... :( – Jess 2013-10-02 01:34:46

+0

@Jess,我承認這裏的錯誤處理是天真的,但我很好奇你在看什麼。理論上,任何異常都應該被域捕獲,並提供作爲一個「錯誤」參數的堆棧,假設你的處理程序有一個 – 2013-10-02 16:46:42

+0

我使用sequelize,它會拋出一個異常,如果where子句沒有有效的語法,例如我不能改變代碼t o'發射'而不是'扔'。我已經嘗試了這裏列出的所有解決方案,但似乎沒有發現拋出的錯誤。 – Jess 2013-10-02 19:37:33

2

這是一個很晚的答案,但請查看express-domain-moddleware模塊。它會自動爲每個請求創建一個新域。活動域可以由您的路由中的process.domain引用。這裏有一個例子:

//with domain-middleware 
app.use(require('express-domain-middleware')); 
app.use(app.router); 

app.use(function errorHandler(err, req, res, next) { 
    console.log('error on request %d %s %s: %j', process.domain.id, req.method, req.url, err); 
    res.send(500, "Something bad happened. :("); 
    if(err.domain) { 
    //you should think about gracefully stopping & respawning your server 
    //since an unhandled error might put your application into an unknown state 
    } 
}); 

app.get('/error', function(req, res, next) { 
    db.query('SELECT happiness()', process.domain.intercept(function(rows) { 
    fs.readFile('asldkfjasdf', process.domain.intercept(function(contents) { 
     process.nextTick(process.domain.intercept(function() { 
     throw new Error("The individual request will be passed to the express error handler, and your application will keep running."); 
     })); 
    })); 
    })); 
}); 
+0

我對此表示贊同,因爲'express-domain-middleware'看起來像這個問題最好的答案(並且仍然保留)。與同一作者的'node-ok'一起看起來像是一個可靠的解決方案,用於node/express中的錯誤處理。我將添加一個與同一主題有點相關的鏈接:一旦它們被捕獲,如何響應錯誤:https://github.com/hapijs/boom – 2014-12-03 20:12:35