如何创建Express/Connect中间件,将每个请求包装在自己的域中?
我想使用Node.js域来捕获异常.它到目前为止工作,但有一个地方我无法获得域来捕获异常.回调中的exception2在domain.on('error')处理程序中被捕获和处理,但是没有捕获exception1.奇怪的是,当抛出exception1时,它不像我期望的那样关闭Node.这是我的示例应用程序:
var domain = require('domain');
var request = require('request');
var express = require('express');
var serverDomain = domain.create();
serverDomain.on('error', function(err) {
console.log("Server Domain Error: " + err);
});
var app;
serverDomain.run(function() {
app = express();
app.listen(3000);
});
app.use(function(req, res, next) {
var reqDomain = domain.create();
reqDomain.add(req);
reqDomain.add(res);
reqDomain.on('error', function(err) {
console.log("Req Domain Error: " + err);
reqDomain.dispose();
next(err);
});
next();
});
app.get('/', function(req, res) {
var uri = "http://google.com";
exception1.go();
request.get({url:uri, json: {}},
function (error, response, body) {
if(response.statusCode === 200) …Run Code Online (Sandbox Code Playgroud) 我们可以使用require函数访问本地模块,但不能通过它访问全局模块.我在某处读到要使用全局模块,我们需要将其设置为本地,然后通过require函数导入它.因此,如果我们无法直接访问全局模块,那么使用它的需求是什么.
我已经在Node上阅读了几个小时的异常处理.我理解使用的缺点uncaughtException,我知道关闭这个过程有利于防止任何"未知状态","任何事情都可能发生".我理解使用域是一种方法,我理解如何正确实现域,特别是显式绑定 ...
...但我仍然没有得到任何结果只是基本的错误处理.
我希望能够捕获任何未捕获的异常以进行日志记录.我不介意杀死这个过程或任何其他被认为是"不受欢迎的".我只想要一个日志.
我不觉得我应该把所有东西都包在try/catch中或者使用一些库来解决emit错误...如果我错了请纠正我,我会改变我的方式.
我正在使用Node和Express,我有以下简单的代码:
var express = require('express');
var domain = require('domain');
var serverDomain = domain.create();
serverDomain.on('error', function(err) {
console.log("SERVER DOMAIN ERROR: " + err.message);
});
serverDomain.run(function() {
var app = express();
app.get('/testing', function() {
app.nonExistent.call(); // this throws an error
});
var server = app.listen(8000, function() {
console.log('Listening on port %d', server.address().port);
});
});
Run Code Online (Sandbox Code Playgroud)
错误显示在控制台中,但控制台从未收到"SERVER DOMAIN ERROR ..."消息.我也尝试在自己的域中包装请求/响应,但无济于事.更令人失望的是,使用以下内容也不起作用:
process.on('uncaughtException', function(err) {
console.log('uncaughtException caught the error');
});
Run Code Online (Sandbox Code Playgroud)
难道我做错了什么?我从哪里开始?我怎样才能发现上述错误?
我刚刚开始在nodejs中使用域来进行错误管理.
当我将它们与socket.io一起使用时,我无法理解.
这是我的示例代码:
io.sockets.on('connection', function cb1(socket){
socket.on('event', function cb2(data){
});
});
Run Code Online (Sandbox Code Playgroud)
我开始将所有代码都放在"run"方法中
domain.run(function(){
io.sockets.on('connection', function cb1(socket){
socket.on('event', function cb2(data){
});
});
});
Run Code Online (Sandbox Code Playgroud)
但如果在cb1或cb2中发生错误,则不会处理!
然后我在che cb1上使用了bind methon
domain.run(function(){
io.sockets.on('connection', domain.bind(function cb1(socket){
socket.on('event', function cb2(data){
});
}));
});
Run Code Online (Sandbox Code Playgroud)
但如果在cb2中发生错误则不会处理!
我的问题是:我是否必须在每次回调中添加一个"绑定"?在服务器和所需的文件中?
当我开始研究领域时,所有教程都将它们定义为在一个点上处理错误的最佳解决方案!
我错过了什么吗?
我的用例要求node.js域在请求级别跨服务器文件共享信息.
express.js中的示例实现
domain = require('domain');
app.use(function(req, res, next) {
var reqDomain = domain.create();
reqDomain.add(req);
reqDomain.add(res);
reqDomain.run(next);
});
Run Code Online (Sandbox Code Playgroud)
Nodejs域显式绑定的更多解释
在controller/service中 - process.domain将为您提供上面创建的域并且您可以轻松地将值绑定到此域.例如:
process.domain.obj = {};
Run Code Online (Sandbox Code Playgroud)
这种解释足以理解域的用法.
问题
将域用于多个请求是否安全?
如何确保process.domain对于不同的请求是不同的而不是相同的?
我还想知道在继续本地存储中如何处理这些问题
javascript node.js thread-local-storage express node.js-domains
我遇到了domain模块问题.目前,我正在尝试捕获请求中抛出的任何未捕获的错误.使用express中间件和域.所有请求都在通过此功能之前进行路由,然后再调用next并转移到正确的路由.
app.use (req, res, next) ->
domain = createDomain()
domain.on "error", (err) ->
res.send(500)
domain.dispose()
domain.enter()
next()
Run Code Online (Sandbox Code Playgroud)
问题是,如果永远不会抛出错误,我该如何处置域?
我可以在中间装置之外提升领域和事件,所以我不需要处理,但是我将无法访问需要发送500的中间装备.
有没有人有更好的解决方案,我如何处理这个?我花了太多时间试图找出一种方法(以及许多hacky方式)来处理这个问题.谢谢.
当运行利用域进行错误处理的测试时,即使库中的域处理程序应该捕获错误,Mocha仍然会抛出错误.如果我在Mocha之外执行代码,它的功能正确,让我相信问题是Mocha.
例:
foo.js
module.exports = function(done) {
var domain = require("domain");
var d = domain.create();
d.on("error", function() {
done();
});
d.run(function() {
throw new Error("foo");
});
}
Run Code Online (Sandbox Code Playgroud)
test.js - foo.js域内没有捕获到内部错误.
describe("test", function() {
it("should succeed", function(done) {
var foo = require("./foo.js");
foo(function() {
console.log("done");
done();
});
});
});
result : error thrown
Run Code Online (Sandbox Code Playgroud)
script.js - 域正确捕获错误并冒泡.
var foo = require("./foo.js");
foo(function() {
console.log("done");
});
result : done
Run Code Online (Sandbox Code Playgroud)
正如您在上面所看到的,如果我直接将节点定向到script.js其功能,则域处理程序将捕获错误并继续执行代码.如果我在Mocha测试中运行相同的代码块,则错误将暂停测试并给出失败.我相信这是因为错误是在uncaughtException处理程序或类似的东西上发送的.另一个复杂的问题是它在Mocha中正常工作,如果我在函数调用周围有一个process.nextTick(),让我相信Mocha只能处理同步错误,但是对于异步错误可以正常工作.
这里有一些关于这个问题的讨论:https://groups.google.com/forum/#! msg/nodejs /n- W9BSfxCjI/ …
使用同步错误,您可以嵌套如下错误范围:
try {
try {
throw Error('e')
} catch(e) {
if(e.message !== 'f')
throw e
}
} catch(e) {
handleError(e)
}
Run Code Online (Sandbox Code Playgroud)
这是我希望它能起作用的方式,但是却没有(似乎在域错误处理程序内部的错误被抛出到顶部,跳过了两者之间的任何域):
var domain = require('domain');
var dA = domain.create();
dA.on('error', function(err) {
console.log("dA: "+ err); // never happens
});
dA.run(function() {
var dB = domain.create();
dB.on('error', function(err) {
throw err
});
dB.run(function() {
setTimeout(function() {
console.log('dB')
throw 'moo'
},0)
});
});
Run Code Online (Sandbox Code Playgroud)
有办法做到这一点吗?
node.js ×9
express ×5
javascript ×3
dns ×2
exception ×1
middleware ×1
mocha.js ×1
npm ×1
socket.io ×1