繁体   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