2015-11-05 59 views
0

我遇到了NodeJS中的域問題。我已經設置了一些中間件功能,以便域名在我的Web應用程序中進行每次呼叫時都會進行包裝。我的目標是能夠收集發生的任何錯誤,處理它,並返回有關發生錯誤的有用信息。NodeJS域錯誤處理無法啓動ReferenceError

這適用於大多數錯誤,但我看到該域沒有看到,或者在ReferenceError上觸發我的事件處理程序。我已經嘗試了很多東西,並環顧了很多地方,但無濟於事。我認爲在一個錯誤和一個異常之間可能有區別,但這是未經證實的。

我注意到,因爲我正在偵聽Error事件,所以可能沒有像ReferenceError這樣的一些類型的錯誤觸發這樣的事件。

我試着在process.nextTick中包裝我的代碼,並在async.js塊中放入錯誤的代碼。

我試過用https://github.com/brianc/node-domain-middleware作爲修復。

我試過監聽域的錯誤事件,並偵聽EventEmitter並將該發射器添加到域中。

以及,使用域對象本身的進入和退出方法。我相信現在還有更多事情我不能確切記得。

真的,我正在尋找的是一個解決方案,它將捕獲在我的nodejs web應用程序中發生的任何錯誤,並允許我處理髮生的錯誤。

有一個總體中間件每次都執行,而中間件只能在api調用上運行。 api調用的中間件會檢查您是否已通過身份驗證(哪些可以在應用程序的另一部分中運行並進行驗證)。

是的,我已經嘗試在這些中間件內部爲每個請求創建一個域,並且我嘗試創建並將這些error_handling_domain.run語句按照每個可以在這兩個中間件之間進行的順序和組合進行放置。每次它總是相同的,沒有錯誤處理程序觸發的輸出或信號。

代碼:

var error_handling_domain = domain.create(); 
 
    var EventEmitter = require('events').EventEmitter; 
 
    var emitter = new EventEmitter(); 
 

 
    error_handling_domain.on('error', function(er) { 
 
     console.log("i caught an error"); 
 
     console.log(er); 
 
    }); 
 

 
    emitter.on('error', function(err) { 
 
     console.log("I am an emitter error"); 
 
     console.log(err); 
 
    }); 
 

 
    error_handling_domain.add(emitter); 
 

 
    app.use(function(req, res, next) { 
 
     error_handling_domain.run(function() { 
 
     next(); 
 
     }); 
 
    }); 
 

 
    app.all('/api/*', function(req, res, next) { 
 
     var original_url_prefix = req.originalUrl.split('/')[1]; 
 
     original_url_prefix = (original_url_prefix) ? original_url_prefix.toLowerCase() : ""; 
 
     req.user = "me"; 
 
     var authentication_required = original_url_prefix === 'api' && !req.user; 
 
     if (authentication_required) { 
 
     res.sendStatus(401); 
 
     } else { 
 
     next(); 
 
     } 
 
    }); 
 

 
app.post('/api/my_route/here', handle_post); 
 

 
function handle_post(req, resp){ 
 
    switch(req.body.action){ 
 
    case 'download': this.download_report(req.body, resp); 
 
    } 
 
} 
 

 
function download_report(params, resp){  
 
    wellhi.thing;  
 
    resp.json({success: "I guess"}); 
 
}

假設我發表的帖子中 '/ API/my_route /在這裏',download_report被調用,並試圖引用wellhi.thing這顯然不是一個真實的東西。這是我正在使用的測試錯誤代碼。

我正在使用NodeJS和expressjs。我一直在試圖獲得非常熟悉以下網頁:

https://nodejs.org/api/errors.html#errors_class_referenceerror

http://tuttlem.github.io/2015/05/16/handling-exceptions-with-domains-in-nodejs.html

https://strongloop.com/strongblog/robust-node-applications-error-handling/

https://nodejs.org/api/domain.html http://www.lighthouselogic.com/node-domains-as-a-replacement-for-try-catch/

#2帖子中,我看了看:

Domains not properly catching errors while testing nodeJS in mocha

NodeJS Domains and expressjs

請讓我知道如果有更多的信息,我可以添加到這個幫助澄清。

回答

0

我已經接受了,似乎沒有辦法完全處理每個使用域的錯誤,遺憾的是。

我所做的遠不是我想要的 - 我已經在其他路由之後特別設置了expressjs錯誤處理路由。我已經將錯誤處理隔離到它自己的函數中,並且Domain和expressjs路由指向該錯誤處理函數。

無論出於何種原因,這似乎可以捕獲領域拒絕捕獲的意外錯誤(如ReferenceError)。因此,我同時使用錯誤捕獲。我有點擔心這種方法可能存在重疊和潛在的衝突。

純粹的猜想:似乎有些錯誤不會發出錯誤事件,這可能是域不能觸發的原因。

的戰略,然後一直:

  • 域:錯誤,我可以預言//專門拋出//觀看
  • Expressjs:意外錯誤,我無法預測

代碼:

function error_handling(err, req, res) { 
 
    console.log("hello im an error."); 
 
} 
 

 
var error_handling_domain = domain.create(); 
 
error_handling_domain.on("error", error_handling); 
 

 
app.use(function(req, res, next) { 
 
    error_handling_domain.run(function(){     
 
    next(); 
 
    });  
 
}); 
 

 
app.use('/api', function(req, res, next){  
 
    var authentication_required = <check_for_auth>; 
 
    if(authentication_required) { 
 
    res.sendStatus(401);     
 
    } else {   
 
    next();     
 
    } 
 
}); 
 

 
var routes = require('routes.js'); 
 
routes.initialize(app); 
 

 
app.use(function(err, req, res, next) { 
 
    error_handling(err, req, res) 
 
});