Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node.js process.domain is undefined sometimes

Tags:

node.js

In Node.js project build with LoopbackJS I need to store data during request.

So I used domain feature:

// 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);
});

Later in required module:

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
})

BUT when I make request from Safari or IE, process.domain is sometimes undefined! Requesting from Chrome or Firefox works as expected. Any suggestions?

Error response:

{"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)"}}
like image 248
IvanZh Avatar asked Feb 27 '15 12:02

IvanZh


2 Answers

Just found out, that explisity binding req and res to domain at creation moment, solves undefined domains down in execution stack.

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()
  });
});

Don't know why this happens, so I leave question open for other possible advices.

like image 65
IvanZh Avatar answered Sep 28 '22 14:09

IvanZh


It is worth mentioning that domains are not meant to be used to handle errors in this manner. Domains are instead meant to be used to allow modules of an entire application to crash safely (for example, maybe you want to run 3rd party code in a sandbox). A domain is not necessary here (though you are, of course, free to use one)

Furthermore, process.domain is only set if the given function is executing from within the domain stack. You do not provide information about the Model's call site, so I can only assume that your model is being called from outside of this stack, which is causing the error.

Given that you're hooking to beforeRemote, which executes before a remote action is executed, I'm going to assume that is being called from outside of the domain stack, and thus process.domain being undefined is expected behaviour.

like image 36
Dan Avatar answered Sep 28 '22 14:09

Dan