簡體   English   中英

使用node.js進行Javascript異步異常處理

[英]Javascript Asynchronous Exception Handling with node.js

我目前正在研究node.js應用程序,我遇到了常見的異步代碼問題。

我正在Node的HTTP模塊上實現一個服務服務器。

此服務器支持(表示類似)路由。 例如,我的代碼如下所示:

server.any("/someRoute",function(req,resp){
    resp.end("this text is sent to clients via http")
});

服務器需要能夠承受故障,當傳遞給任何一個函數時出現問題時,我不想讓整個服務器崩潰。 當我編寫的代碼如下所示時會出現問題:

server.any("/someRoute",function(req,resp){
    setTimeout(function(){
        throw new Error("This won't get caught");
    },100);
});

我不知道我怎么可能在這里發現錯誤。 我不想讓服務器崩潰超過一個服務器端故障,而是我想服務500。

我能夠提出的唯一解決方案實際上並不富有表現力。 我只是想出使用process.on("uncaughtException",callback)和使用節點0.8 Domains類似代碼(這是一種部分補救措施但是域名目前是錯誤的,因為我最終不得不創建每個句柄的域名)。

我想要完成的是throw函數從一個函數綁定到一個作用域,理想的解決方案是將所有拋出的錯誤從一個函數綁定到一個特定的處理函數。

這可能嗎? 在這種情況下處理錯誤的最佳做法是什么?

我想強調它應該能夠在一個錯誤的請求后繼續提供請求,並在每個請求上重新啟動服務器或為每個處理程序創建域並捕獲未捕獲的異常對我來說似乎是一個壞主意。 另外 - 我聽說過承諾可以幫助我(有關throw承諾的事情),在這種情況下可以承諾幫助我嗎?

警告 :我不推薦使用域名的原始答案,將來不推薦使用域名,我寫了原始答案時有很多樂趣,但我不再相信它太相關了。 相反 - 我建議使用具有更好錯誤處理的事件發射器和承諾 - 以下是帶有promises的示例。 這里使用的承諾是藍鳥

Promise.try(function(){ 
    throw new Error("Something");
}).catch(function(err){
    console.log(err.message); // logs "Something"
});

超時(注意我們必須返回Promise.delay):

Promise.try(function() {
    return Promise.delay(1000).then(function(){
        throw new Error("something");
    });
}).catch(function(err){
    console.log("caught "+err.message);
});

使用一般的NodeJS功能:

var fs = Promise.promisifyAll("fs"); // creates readFileAsync that returns promise
fs.readFileAsync("myfile.txt").then(function(content){
    console.log(content.toString()); // logs the file's contents
    // can throw here and it'll catch it
}).catch(function(err){
    console.log(err); // log any error from the `then` or the readFile operation
});

這種方法既快速又安全,我推薦它高於下面的答案,它使用的域名可能不會留下來。


我最終使用域名,我創建了以下文件,我稱之為mistake.js ,其中包含以下代碼:

var domain=require("domain");
module.exports = function(func){
    var dom = domain.create();
    return { "catch" :function(errHandle){
        var args = arguments;
        dom.on("error",function(err){
            return errHandle(err);
        }).run(function(){
            func.call(null, args);
        });
        return this;
    };
};

以下是一些示例用法:

var atry = require("./mistake.js");

atry(function() {
    setTimeout(function(){
        throw "something";
    },1000);
}).catch(function(err){
    console.log("caught "+err);
});

它也像普通的同步代碼捕獲一樣工作

atry(function() {
    throw "something";
}).catch(function(err){
    console.log("caught "+err);
});

我將很感激對該解決方案的一些反饋

另外,在v 0.8中,顯然當你在域中捕獲異常時,它仍然會起泡到process.on("uncaughtException") 我在我的process.on("uncaughtException")處理了這個問題

 if (typeof e !== "object" || !e["domain_thrown"]) {

但是,文檔建議不要以任何方式反對process.on("uncaughtException")

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM