Mongoose create on session fails on validation

时间:2018-12-03 13:06:47

标签: mongodb mongoose

I am trying to create a document, on an existing collection, using MongoDB + async..await programming + session/transaction control (in order to be able to rollback to a previous state if anything goes wrong). The relevant code is shown below:

exports.campaign_totalize = async (campaign, start_date, end_date, now) => {

    var session = await mongoose.startSession();
    session.startTransaction();

    try {
    // ...

            let commission = await commissionModel.create({
                datetime: Date.now(),
                value: 10,
                status: 'issued',
                affiliate: affiliate_id,
                campaign: campaign_id
             }, { session: session });

    // ...
        }

    // ...
    } catch (err) {
        console.log("Error totalizing commissions:", err);
        await session.abortTransaction();
        session.endSession();
        throw err;
    }
}

Executing code above I get ValidationError on ALL fields (even being sure they are all OK). If I remove the session parameter, however, everything works fine! The collections exists for sure.

Below information about my environment:

"dependencies": {
  "express": "^4.16.4",
  "mongoose": "^5.3.9",
  "mongoose-bcrypt": "^1.6.0",
  "validator": "^10.9.0"
}

$ node --version
v10.14.0
$ mongod --version
db version (v3.6.3) -> v4.0.4

Thank you very much.

Update:

As Shivam Pandey pointed out in the comments, mongoDB version starts supporting transactions on version 4.0. I just updated it to 4.0.4 and it is returning the same errors, though.

Update 2: Stack trace:

Trace: error
    at Object.exports.campaign_totalize (/home/luiz/magalabs/magafilio/magafilio-server/logic/commission_calc.js:147:17)
    at process._tickCallback (internal/process/next_tick.js:68:7)
Error totalizing commissions: { ValidationError: Commission validation failed: campaign: All commissions must be associated to a campaign, affiliate: All commissions must be associated to an affiliate, status: Commission needs a status associated, value: Commission needs a value - use 0 for no valued commissions, datetime: Commission needs date/time info
    at ValidationError.inspect (/home/luiz/magalabs/magafilio/magafilio-server/node_modules/mongoose/lib/error/validation.js:59:24)
    at formatValue (internal/util/inspect.js:453:31)
    at inspect (internal/util/inspect.js:193:10)
    at Object.formatWithOptions (util.js:165:18)
    at Console.(anonymous function) (console.js:188:15)
    at Console.log (console.js:199:31)
    at Object.exports.campaign_totalize (/home/luiz/magalabs/magafilio/magafilio-server/logic/commission_calc.js:148:17)
    at process._tickCallback (internal/process/next_tick.js:68:7)
  errors:
   { campaign:
      { ValidatorError: All commissions must be associated to a campaign
          at new ValidatorError (/home/luiz/magalabs/magafilio/magafilio-server/node_modules/mongoose/lib/error/validator.js:29:11)
          at validate (/home/luiz/magalabs/magafilio/magafilio-server/node_modules/mongoose/lib/schematype.js:844:13)
          at /home/luiz/magalabs/magafilio/magafilio-server/node_modules/mongoose/lib/schematype.js:897:11
          at Array.forEach (<anonymous>)
          at ObjectId.SchemaType.doValidate (/home/luiz/magalabs/magafilio/magafilio-server/node_modules/mongoose/lib/schematype.js:853:19)
          at /home/luiz/magalabs/magafilio/magafilio-server/node_modules/mongoose/lib/document.js:1893:9
          at process._tickCallback (internal/process/next_tick.js:61:11)
        message: 'All commissions must be associated to a campaign',
        name: 'ValidatorError',
        properties: [Object],
        kind: 'required',
        path: 'campaign',
        value: undefined,
        reason: undefined,
        [Symbol(mongoose:validatorError)]: true },
     affiliate:
      { ValidatorError: All commissions must be associated to an affiliate
          at new ValidatorError (/home/luiz/magalabs/magafilio/magafilio-server/node_modules/mongoose/lib/error/validator.js:29:11)
          at validate (/home/luiz/magalabs/magafilio/magafilio-server/node_modules/mongoose/lib/schematype.js:844:13)
          at /home/luiz/magalabs/magafilio/magafilio-server/node_modules/mongoose/lib/schematype.js:897:11
          at Array.forEach (<anonymous>)
          at ObjectId.SchemaType.doValidate (/home/luiz/magalabs/magafilio/magafilio-server/node_modules/mongoose/lib/schematype.js:853:19)
          at /home/luiz/magalabs/magafilio/magafilio-server/node_modules/mongoose/lib/document.js:1893:9
          at process._tickCallback (internal/process/next_tick.js:61:11)
        message: 'All commissions must be associated to an affiliate',
        name: 'ValidatorError',
        properties: [Object],
        kind: 'required',
        path: 'affiliate',
        value: undefined,
        reason: undefined,
        [Symbol(mongoose:validatorError)]: true },
     status:
      { ValidatorError: Commission needs a status associated
          at new ValidatorError (/home/luiz/magalabs/magafilio/magafilio-server/node_modules/mongoose/lib/error/validator.js:29:11)
          at validate (/home/luiz/magalabs/magafilio/magafilio-server/node_modules/mongoose/lib/schematype.js:844:13)
          at /home/luiz/magalabs/magafilio/magafilio-server/node_modules/mongoose/lib/schematype.js:897:11
          at Array.forEach (<anonymous>)
          at SchemaString.SchemaType.doValidate (/home/luiz/magalabs/magafilio/magafilio-server/node_modules/mongoose/lib/schematype.js:853:19)
          at /home/luiz/magalabs/magafilio/magafilio-server/node_modules/mongoose/lib/document.js:1893:9
          at process._tickCallback (internal/process/next_tick.js:61:11)
        message: 'Commission needs a status associated',
        name: 'ValidatorError',
        properties: [Object],
        kind: 'required',
        path: 'status',
        value: undefined,
        reason: undefined,
        [Symbol(mongoose:validatorError)]: true },
     value:
      { ValidatorError: Commission needs a value - use 0 for no valued commissions
          at new ValidatorError (/home/luiz/magalabs/magafilio/magafilio-server/node_modules/mongoose/lib/error/validator.js:29:11)
          at validate (/home/luiz/magalabs/magafilio/magafilio-server/node_modules/mongoose/lib/schematype.js:844:13)
          at /home/luiz/magalabs/magafilio/magafilio-server/node_modules/mongoose/lib/schematype.js:897:11
          at Array.forEach (<anonymous>)
          at SchemaNumber.SchemaType.doValidate (/home/luiz/magalabs/magafilio/magafilio-server/node_modules/mongoose/lib/schematype.js:853:19)
          at /home/luiz/magalabs/magafilio/magafilio-server/node_modules/mongoose/lib/document.js:1893:9
          at process._tickCallback (internal/process/next_tick.js:61:11)
        message: 'Commission needs a value - use 0 for no valued commissions',
        name: 'ValidatorError',
        properties: [Object],
        kind: 'required',
        path: 'value',
        value: undefined,
        reason: undefined,
        [Symbol(mongoose:validatorError)]: true },
     datetime:
      { ValidatorError: Commission needs date/time info
          at new ValidatorError (/home/luiz/magalabs/magafilio/magafilio-server/node_modules/mongoose/lib/error/validator.js:29:11)
          at validate (/home/luiz/magalabs/magafilio/magafilio-server/node_modules/mongoose/lib/schematype.js:844:13)
          at /home/luiz/magalabs/magafilio/magafilio-server/node_modules/mongoose/lib/schematype.js:897:11
          at Array.forEach (<anonymous>)
          at SchemaDate.SchemaType.doValidate (/home/luiz/magalabs/magafilio/magafilio-server/node_modules/mongoose/lib/schematype.js:853:19)
          at /home/luiz/magalabs/magafilio/magafilio-server/node_modules/mongoose/lib/document.js:1893:9
          at process._tickCallback (internal/process/next_tick.js:61:11)
        message: 'Commission needs date/time info',
        name: 'ValidatorError',
        properties: [Object],
        kind: 'required',
        path: 'datetime',
        value: undefined,
        reason: undefined,
        [Symbol(mongoose:validatorError)]: true } },
  _message: 'Commission validation failed',
  name: 'ValidationError' }

1 个答案:

答案 0 :(得分:0)

我认为您如何使用创建方式存在问题,或者至少这是我的第一个猜测。

  

要指定选项,文档必须是数组,而不是点差。

https://mongoosejs.com/docs/api.html#model_Model.create

必须采用这种形式

Model.create([doc], options)

你有

Model.create(doc, options)

这可能就是您想要的

let [commission] = await commissionModel.create([{datetime: Date.now(), 
...}], {session})

let [commission] = await commissionModel.create([doc], options})

当您将数组传递给Model.create()时,Model.create()将返回一个包含您创建/保存的文档的数组,因此这就是为什么我使用“ let [commission]”(将[commission])设置为第一个变量返回数组中的项。