"Meteor code must always run within a Fiber" when calling Collection.insert on server

Andrew Beresford picture Andrew Beresford · Apr 17, 2012 · Viewed 20.2k times · Source

I have the following code in server/statusboard.js;

var require = __meteor_bootstrap__.require,
    request = require("request")   


function getServices(services) {
  services = [];
  request('http://some-server/vshell/index.php?type=services&mode=json', function (error, response, body) {
    var resJSON = JSON.parse(body);
     _.each(resJSON, function(data) {
       var host = data["host_name"];
       var service = data["service_description"];
       var hardState = data["last_hard_state"];
       var currState = data["current_state"];
       services+={host: host, service: service, hardState: hardState, currState: currState};
       Services.insert({host: host, service: service, hardState: hardState, currState: currState});
    });
  });
}

Meteor.startup(function () {
  var services = [];
  getServices(services);
  console.log(services);
});

Basically, it's pulling some data from a JSON feed and trying to push it into a collection.

When I start up Meteor I get the following exception;

app/packages/livedata/livedata_server.js:781
      throw exception;
            ^
Error: Meteor code must always run within a Fiber
    at [object Object].withValue (app/packages/meteor/dynamics_nodejs.js:22:15)
    at [object Object].apply (app/packages/livedata/livedata_server.js:767:45)
    at [object Object].insert (app/packages/mongo-livedata/collection.js:199:21)
    at app/server/statusboard.js:15:16
    at Array.forEach (native)
    at Function.<anonymous> (app/packages/underscore/underscore.js:76:11)
    at Request._callback (app/server/statusboard.js:9:7)
    at Request.callback (/usr/local/meteor/lib/node_modules/request/main.js:108:22)
    at Request.<anonymous> (/usr/local/meteor/lib/node_modules/request/main.js:468:18)
    at Request.emit (events.js:67:17)
Exited with code: 1

I'm not too sure what that error means. Does anyone have any ideas, or can suggest a different approach?

Answer

imslavko picture imslavko · Aug 30, 2013

Just wrapping your function in a Fiber might not be enough and can lead to unexpected behavior.

The reason is, along with Fiber, Meteor requires a set of variables attached to a fiber. Meteor uses data attached to a fiber as a dynamic scope and the easiest way to use it with 3rd party api is to use Meteor.bindEnvironment.

T.post('someurl', Meteor.bindEnvironment(function (err, res) {
  // do stuff
  // can access Meteor.userId
  // still have MongoDB write fence
}, function () { console.log('Failed to bind environment'); }));

Watch these videos on evented mind if you want to know more: https://www.eventedmind.com/posts/meteor-dynamic-scoping-with-environment-variables https://www.eventedmind.com/posts/meteor-what-is-meteor-bindenvironment