2

I am trying to use twit in Meteor in order to communicate to the Twitter REST api.

It works fine in say a server.js file in the /server/ directory if I call it by itself. If I wrap or call it from within say an observe or even call a function that calls twit's functions from an observe I get errors.

For example this works perfectly fine within a /server/server.js.

T.post('statuses/update', { status: 'hello world!' }, function(err, reply) {
  console.log('error: ' + JSON.stringify(err,0,4));
  console.log('reply: ' + JSON.stringify(reply,0,4));
});

But, suppose I want to say call Twitter every time a record is inserted.

var query = Posts.find({}, {fields: {}});

var handle = query.observe({
added: function(post, before_index){
    if(post.twitter_id_str === undefined || post.twitter_id_str === '' ||
        post.twitter_id_str === null) { 

        T.post('statuses/update', { status: 'hello world!' }, function(err, reply) {
          console.log('error: ' + JSON.stringify(err,0,4));
          console.log('reply: ' + JSON.stringify(reply,0,4));
          if(reply){
            // TODO update record with twitter id_str
                            //  BREAKS here - crash, restart
            console.log('incoming twitter string: ' + reply.id_str);
            Posts.update(
                {_id: post._id},
                {$set:{twitter_id_str:reply.id_str}}
            );
        }
});
    } else {
        console.log('remove me we have it: ' + post.twitter_id_str);
    }   
}
});

Which throws this error, server crashes and restarts but no code logic is run where I have commented the Break.

app/packages/mongo-livedata/collection.js:215
        throw e;
          ^
Error: Meteor code must always run within a Fiber
    at [object Object].get (app/packages/meteor/dynamics_nodejs.js:14:15)
    at [object Object]._maybeBeginWrite (app/packages/mongo-livedata/mongo_driver.js:68:41)
    at [object Object].update (app/packages/mongo-livedata/mongo_driver.js:191:20)
    at [object Object].update (app/packages/mongo-livedata/collection.js:203:32)
    at app/server/server.js:39:13
    at /usr/lib/meteor/lib/node_modules/twit/lib/oarequest.js:85:16
    at passBackControl (/usr/lib/meteor/lib/node_modules/twit/node_modules/oauth/lib/oauth.js:359:11)
    at IncomingMessage.<anonymous> (/usr/lib/meteor/lib/node_modules/twit/node_modules/oauth/lib/oauth.js:378:9)
    at IncomingMessage.emit (events.js:88:20)
    at HTTPParser.onMessageComplete (http.js:137:23)
Exited with code: 1

In summary, the Twitter code runs fine on it's own but not when within the Meteor fibers stuff. I tried putting it in another function and calling that from within the observe etc... no avail.

Any recommendations or ideas?

Steeve Cannon
  • 3,682
  • 3
  • 36
  • 49

1 Answers1

4

You'll need to do the twit post API call in a fiber:

Fiber(function() { ... your twit API call ... }).run()

Have a look at this related question: "Meteor code must always run within a Fiber" when calling Collection.insert on server

Community
  • 1
  • 1
mz2
  • 4,672
  • 1
  • 27
  • 47