Javascript异步异常处理与node.js [英] Javascript Asynchronous Exception Handling with node.js
问题描述
我正在使用一个node.js应用程序,而且我遇到了常见的异步代码问题。
I'm currently working on a node.js app and I'm having the usual asynchronous code issue.
我正在实现一个服务服务器节点的HTTP模块。
I'm implementing a service server on top of Node's HTTP module.
此服务器支持(表达式)路由。
例如我的代码看起来像这样:
This server supports (express like) routes. For example I have code that looks like this:
server.any("/someRoute",function(req,resp){
resp.end("this text is sent to clients via http")
});
服务器需要能够承受故障,我不想在整个服务器崩溃时是传递给任何一个函数的问题。当我编写的代码看起来像:
The server needs to be able to withstand failure, I do not want to crash the whole server when there is a problem in a function passed to any. The problem occurs when I'm writing code that looks like:
server.any("/someRoute",function(req,resp){
setTimeout(function(){
throw new Error("This won't get caught");
},100);
});
我没有看到我可以抓到这里的错误。我不想让服务器崩溃一个服务器端的故障,而是我要提供500.
I don't see how I possible can catch the error here. I don't want to crash the server over one server-side glitch, instead I want to serve 500.
我已经能够提出的唯一解决方案真的没有表现力。我只想到使用 process.on(uncaughtException,回调)
和使用节点0.8的类似代码域
(这是一个部分补救措施,但域名目前是错误的,这仍然不是很有表现力,因为我最终不得不为每个句柄创建一个域)。
The only solutions I've been able to come up with are really not expressive. I've only come up with using process.on("uncaughtException",callback)
and similar code using node 0.8 Domains
(which is a partial remedy but Domains are currently buggy and this is still not very expressive since I end up having to create a domain for every handle).
我想要完成的是将功能绑定到一个范围,理想的解决方案是例如将所有抛出的错误从一个函数绑定到一个特定的处理函数。
What I would like to accomplish is binding throw
actions from a function to a scope, the ideal solution is something like binding all thrown errors from a function to a specific handler function.
这可能吗?在这种情况下处理错误的最佳做法是什么?
Is this possible? What is the best practice to handle errors in this case?
我想强调,应该能够在糟糕的请求后继续提供请求,并重新启动服务器在每个请求或为每个处理程序创建域,捕捉他们未捕获的异常似乎是一个坏主意对我来说。另外 - 我听说过承诺可能会帮助我(在承诺中有关 throw
),可以承诺在这种情况下帮助我吗?
I'd like to emphasise that it should be able to continue serving requests after a bad requests, and restarting the server on every request or creating domains for every handler and catching their uncaught exceptions seems like a bad idea to me. Additionally - I've heard promises might be able to assist me (something about throw
in promises), can promises aid me in this situation?
推荐答案
警告:我不会推荐使用域名的原始答案,未来域名将被弃用,我有很多乐趣写出原来的答案,但我不再相信这太相关了。相反,我建议使用事件发射器和承诺,有更好的错误处理 - 这是下面的承诺的例子。这里使用的承诺是蓝鸟:
Warning: I would not recommend the original answer using domains, domains are being deprecated in the future, I had a lot of fun writing the original answer but I no longer believe it is too relevant. Instead - I suggest using event emitters and promises that have better error handling - here is the below example with promises instead. The promises used here are Bluebird:
Promise.try(function(){
throw new Error("Something");
}).catch(function(err){
console.log(err.message); // logs "Something"
});
有一个超时(请注意,我们必须返回Promise.delay):
With a timeout (note that we have to return the Promise.delay):
Promise.try(function() {
return Promise.delay(1000).then(function(){
throw new Error("something");
});
}).catch(function(err){
console.log("caught "+err.message);
});
使用一般的NodeJS功能:
With a general NodeJS funciton:
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
});
这种方法既快速又可靠,我推荐使用以下答案,可能不在这里留下。
This approach is both fast and catch safe, I recommend it above the below answer which uses domains that are likely not here to stay.
我最终使用域名,我创建了以下文件我叫 mistake.js
其中包含以下代码:
I ended up using domains, I have created the following file I called mistake.js
which contains the following code:
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);
});
它的工作原理与正常抓取同步代码
It also works like normal catch for synchronous code
atry(function() {
throw "something";
}).catch(function(err){
console.log("caught "+err);
});
我希望有一些有关解决方案的反馈
I would appreciate some feedback on the solution
在一个侧面注释中,在v 0.8中,当你捕获域中的异常时,它仍然会起泡到 process.on(uncaughtException)
。我在我的 process.on(uncaughtException)
中与
On a side note, in v 0.8 apparently when you catch the exception in the domain it still bubbles to process.on("uncaughtException")
. I dealt with this in my process.on("uncaughtException")
with
if (typeof e !== "object" || !e["domain_thrown"]) {
但是,文档建议反对 process.on(uncaughtException)
任何方式
However, the documentation suggests against process.on("uncaughtException")
any way
这篇关于Javascript异步异常处理与node.js的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!