Agenda: Error: cyclic dependency detected

Created on 21 Dec 2017  路  6Comments  路  Source: agenda/agenda

While using Agenda, I accidentally attached a Sequelize model instance, instead of a plain JS object. This triggered a rather cryptic error, generated by MongoDB, as the object couldn't be serialized.

Uncaught Error: cyclic dependency detected
      at serializeObject (node_modules/bson/lib/bson/parser/serializer.js:296:33)
      at serializeInto (node_modules/bson/lib/bson/parser/serializer.js:776:17)
      at serializeObject (node_modules/bson/lib/bson/parser/serializer.js:308:18)
      at serializeInto (node_modules/bson/lib/bson/parser/serializer.js:776:17)
      at serializeObject (node_modules/bson/lib/bson/parser/serializer.js:308:18)
      at serializeInto (node_modules/bson/lib/bson/parser/serializer.js:776:17)
      at serializeObject (node_modules/bson/lib/bson/parser/serializer.js:308:18)
      at serializeInto (node_modules/bson/lib/bson/parser/serializer.js:776:17)
      at serializeObject (node_modules/bson/lib/bson/parser/serializer.js:308:18)
      at serializeInto (node_modules/bson/lib/bson/parser/serializer.js:776:17)
      at serializeObject (node_modules/bson/lib/bson/parser/serializer.js:308:18)
      at serializeInto (node_modules/bson/lib/bson/parser/serializer.js:618:17)
      at serializeObject (node_modules/bson/lib/bson/parser/serializer.js:308:18)
      at serializeInto (node_modules/bson/lib/bson/parser/serializer.js:776:17)
      at BSON.serialize (node_modules/bson/lib/bson/bson.js:58:27)
      at Query.toBin (node_modules/mongodb-core/lib/connection/commands.js:140:25)
      at Pool.write (node_modules/mongodb-core/lib/connection/pool.js:986:23)
      at executeWrite (node_modules/mongodb-core/lib/wireprotocol/3_2_support.js:73:10)
      at WireProtocol.insert (node_modules/mongodb-core/lib/wireprotocol/3_2_support.js:84:3)
      at Server.insert (node_modules/mongodb-core/lib/topologies/server.js:564:35)
      at Server.insert (node_modules/mongodb/lib/server.js:390:17)
      at insertDocuments (node_modules/mongodb/lib/collection.js:743:19)
      at insertOne (node_modules/mongodb/lib/collection.js:438:3)
      at Collection.insertOne (node_modules/mongodb/lib/collection.js:426:44)
      at Agenda.module.exports [as saveJob] (node_modules/agenda/lib/agenda/save-job.js:95:22)
      at Job.module.exports [as save] (node_modules/agenda/lib/job/save.js:9:15)
      at Agenda.module.exports [as now] (node_modules/agenda/lib/agenda/now.js:19:7)

I'd suggest that agenda attempt to serialize objects before passing them directly to the mongo driver, and if not possible, throws a more descriptive error.

discussion docs PR required

Most helpful comment

Hi guys,
I'm having this problem right now.
Is there anything you would recommend or anything I can do to help?

All 6 comments

@simison @vkarpov15 should we check if object has a toJSON method and call that before saving to DB incase the object is a class, etc?

@OmgImAlexis there's a few alternatives here. The MongoDB driver looks for a toBSON() function before serializing (https://github.com/mongodb/js-bson/pull/231) so you can do stuff like this:

var BSON = require('bson');

var bson = new BSON();

class CustomSerialize {
  toBSON() {
    return 42;
  }
}

const obj = { answer: new CustomSerialize() };
// "{ answer: 42 }"
console.log(bson.deserialize(bson.serialize(obj)));

I put in a PR to sequelize for supporting that, see sequelize/sequelize#8810 . If they're not interested in supporting that, we can also implement a separate lib like mongodb-moment that attaches the toBSON() function.

I can see the benefit of agenda using toJSON() because very few people are even aware of toBSON() as far as I know. However, if sequelize merges my PR then this issue goes away transparently for agenda and all other mongodb clients (mongoose, connect-mongodb-session, connect-mongo, etc.) so I'd prefer to see what they say first.

Noting here a comment from https://github.com/sequelize/sequelize/pull/8810#issuecomment-354412896:

Yeah, its better if this is handled at application code or as a plugin.

Hi guys,
I'm having this problem right now.
Is there anything you would recommend or anything I can do to help?

@Shahor
Try to include the field which needs to be updated instead of whole object.

I don't think we necessarily need to "fix" it in Agenda but would be good to include this scenario in docs.
PRs welcome!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nhan-pt picture nhan-pt  路  4Comments

michelem09 picture michelem09  路  6Comments

exislow picture exislow  路  5Comments

ruslanjur picture ruslanjur  路  4Comments

ekegodigital picture ekegodigital  路  3Comments