Node.js process.domain有时是未定义的

时间:2015-02-27 12:10:46

标签: node.js

在使用LoopbackJS的Node.js项目构建中,我需要在请求期间存储数据。

所以我使用了domain功能:

// pre-processing middleware
app.use(function (req, res, next) {
  // create per request domain instance
  var domain = require('domain').create();

  // save request and response to domain, to make it accessible everywhere
  domain.req = req;
  domain.res = res;
  domain.run(next);
});

稍后在必需的模块中:

Model.beforeRemote('**', function(oContext, oModel, next) {
    // Save method name for later use
    process.domain.remoteContext = {          /* Here is an error thrown */
      methodName: oContext.method.name
    };
    ...
    process.domain.res.send() // example of usage
})

但是当我从Safari或IE发出请求时,process.domain有时是未定义的! Chrome或Firefox的请求按预期工作。有什么建议吗?

错误回复:

{"error":{"name":"TypeError","status":500,"message":"Cannot set property 'remoteContext' of undefined","stack":"TypeError: Cannot set property 'remoteContext' of undefined\n    at module.exports (/Users/igormatyushkin/projects/Yash/server/hooks/admin-remote.js:12:34)\n    at Function.Model.setup.ModelCtor.beforeRemote.args (/Users/igormatyushkin/projects/Yash/node_modules/loopback/lib/model.js:184:9)\n    at execStack (/Users/igormatyushkin/projects/Yash/node_modules/loopback/node_modules/strong-remoting/lib/remote-objects.js:363:13)\n    at RemoteObjects.execHooks (/Users/igormatyushkin/projects/Yash/node_modules/loopback/node_modules/strong-remoting/lib/remote-objects.js:372:10)\n    at RemoteObjects.invokeMethodInContext (/Users/igormatyushkin/projects/Yash/node_modules/loopback/node_modules/strong-remoting/lib/remote-objects.js:512:8)\n    at async.series.results (/Users/igormatyushkin/projects/Yash/node_modules/loopback/node_modules/strong-remoting/node_modules/async/lib/async.js:610:21)\n    at _asyncMap (/Users/igormatyushkin/projects/Yash/node_modules/loopback/node_modules/strong-remoting/node_modules/async/lib/async.js:249:17)\n    at async.eachSeries.iterate (/Users/igormatyushkin/projects/Yash/node_modules/loopback/node_modules/strong-remoting/node_modules/async/lib/async.js:149:13)\n    at async.eachSeries (/Users/igormatyushkin/projects/Yash/node_modules/loopback/node_modules/strong-remoting/node_modules/async/lib/async.js:165:9)\n    at _asyncMap (/Users/igormatyushkin/projects/Yash/node_modules/loopback/node_modules/strong-remoting/node_modules/async/lib/async.js:248:13)"}}

3 个答案:

答案 0 :(得分:2)

刚刚发现,在创建时,explisity绑定req和res到域,解决了执行堆栈中未定义的域。

app.use(function (req, res, next) {
  // create per request domain instance
  domain.create().run(function() {
    // explicit binding
    process.domain.add(req)
    process.domain.add(res)
    // save request to domain, to make it accessible everywhere
    process.domain.req = req;
    process.domain.res = res;
    next()
  });
});

不知道为什么会这样,所以我提出其他可能的建议。

答案 1 :(得分:1)

值得一提的是域are not meant to be used to handle errors in this manner。相反,域意味着用于允许整个应用程序的模块安全崩溃(例如,您可能希望在沙箱中运行第三方代码)。这里不需要域名(当然,你可以自由使用域名)

此外,仅在给定函数从域堆栈内执行时才设置process.domain。您不提供有关Model的调用站点的信息,因此我只能假设您的模型是从此堆栈外部调用的,这会导致错误。

鉴于您正在挂钩beforeRemote,执行远程操作之前执行,我将假设从域堆栈外部调用,并且因此process.domain未定义是预期的行为。

答案 2 :(得分:1)

对于此问题的读者来说,了解Node's Domain module已被弃用且不应使用,这一点非常重要。

如果你来这里寻找这个问题的解决方案,那么你最好不要寻找域模块以外的东西。

  

此模块正在等待弃用。更新API完成后,将完全弃用此模块。大多数最终用户不应该有使用此模块的原因。绝对必须具有域提供的功能的用户可能暂时依赖它,但是应该期望将来必须迁移到不同的解决方案。

虽然这在技术上并没有回答OP的问题,但我相信它是正确的解决方案"对于这个问题的大多数读者。

使用Domain的替代方法是continuation-local-storage模块。