Skip to content
This repository

Request module seems to affect Backbone (and Underscore) behavior in v0.8 #1543

Closed
mattijs opened this Issue August 11, 2012 · 8 comments

3 participants

Mattijs Hoitink Sam Breed Ted Han
Mattijs Hoitink

The usage of the request module in a node.js v0.8 environment seems to affect Backbone (and Underscore). When the request module is included Backbone refuses to set model values, resulting in an error:

var Backbone = require('backbone');
var request = require('request');

var model = new Backbone.Model();
model.set({ foo: 'bar' }); // works
model.set('foo', 'bar');   // fails

// Results in a TypeError
/.../node_modules/backbone/backbone.js:282
      if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];
                              ^
TypeError: Cannot use 'in' operator to search for 'id' in bar
    at _.extend.set (/.../node_modules/backbone/backbone.js:282:31)
    at Object.<anonymous> (/.../test1.js:36:11)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.runMain (module.js:492:10)
    at process.startup.processNextTick.process._tickCallback (node.js:244:9)

Looking at the code in the set function it seems that the key passes as an object, resulting in the error. This indicates that the Underscore module is affected as well. After moving the require statement passed the model creation the error no longer appears.

I created three simple setups to investigate the error. The setups can be found at https://gist.github.com/3326180 and can be run in node.
test1.js is the failing setup, test2.js is without the request module and test3.js is with the require statement moved.

When run with node v0.8.6 test1 fails and the others pass. But when run with node v0.6.20 all setups pass. Module version used:

  • Backbone 0.9.2 (and master)
  • Underscore 1.3.3
  • Request 2.10.0

The error is generated by Backbone but I'm not sure if this is the right project to report it. The root cause (and fix) might be in the node, request or underscore projects and maybe the issue should be reported there.

Sam Breed
Collaborator

It looks like request is doing something to make _.isObject() fail, so attrs is is getting set improperly.

You should probably open similar issues with Underscore and Request, but Backbone is definitely not the culprit. FWIW Underscore is using just the Object constructor for the comparison, so you may be right to think the root cause is somewhere in Node :hurtrealbad:

Sam Breed
Collaborator

Correction: it seems like what actually happens is that request overwrites anything thing living _ (global or local, doesnt matter). This only happens when initially requiring request, so it can be easily worked around by not loading request after underscore or backbone.

Sam Breed wookiehangover closed this August 14, 2012
Mattijs Hoitink

it can be easily worked around by not loading request after underscore or backbone

Relying on the order of require statements is not a good idea and might not always work. Especially when other modules are in play because the require statements there might be in the wrong order.

It does look like it is a Request (or even Node) issue so I will open a ticket in the Request project. Thanks for your response.

Ted Han
Collaborator

Great. @mattijs, would you mind dropping a link to the Request ticket when you file it?

Mattijs Hoitink

After some more debugging and testing it does look like bug in Node or even in V8.

@knowtheory The Node issue can be found at joyent/node#3867

Sam Breed
Collaborator

wow, that's pretty crazy that Object comparison with the constructor can break like that.

But I'm still curious why including request would squash _.@mattijs have you opened any issues with request about this (even if to just get more eyes on the problem)?

Mattijs Hoitink

I did not open an issue with request yet as I thought opening one in the Node.js project would be enough to solve it eventually.

I could not find any reference of request squashing _. As the Node.js issues shows request might not even squash _ as a comparison somewhere can trigger weird core behavior. It might as well be a v8 optimalisation thing.
The test shows that requiring the punycode module and a comparison like module.exports == exports is enough to trigger the altered behavior. This could mean that request might not be at fault since it simply uses the http module which in turn requires the punycode module.

But it is pretty crazy.

Mattijs Hoitink

It looks like the issue will be fixed in v8 soon: http://code.google.com/p/v8/issues/detail?id=2291

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.