Meteor code must always run within a Fiber. Try wrapping callbacks that you pass to non-Meteor libraries with Meteor.bindEnvironment

I base on Meteor with Mongoose .

  • Sechma
const Schema = new Mongoose.Schema({
  name: {
    type: String,
    required: true,
    max: 200,
  },
  gender: {
    type: String,
  },
  status: {
    type: String,
  },
  comId: {
    type: String,
    required: true,
    default: () => {
      // get current companyId
      return currentComId()
    },
    index: 1,
  },
})
  • Method
export const insertEmployee = new ValidatedMethod({
  name: 'insertEmployee',
  mixins: [CallPromiseMixin],
  validate: null,
  async run(docs) {
    if (Meteor.isServer) {
      try {
        let res = await Employees.insertMany(docs)
        return res
      } catch (error) {
        console.log(error)
      }
    }
  },
})

I tried to insert data but I got error :

W20200611-11:38:41.266(7)? (STDERR)     throw new Error("Meteor code must always run within a Fiber. " +
W20200611-11:38:41.267(7)? (STDERR)     ^
W20200611-11:38:41.267(7)? (STDERR)
W20200611-11:38:41.267(7)? (STDERR) Error: Meteor code must always run within a Fiber. Try wrapping callbacks that you pass to non-Meteor libraries with Meteor.bindEnvironment.
W20200611-11:38:41.267(7)? (STDERR)     at Object.Meteor._nodeCodeMustBeInFiber (packages/meteor.js:1186:11)
W20200611-11:38:41.267(7)? (STDERR)     at Meteor.EnvironmentVariable.EVp.get (packages/meteor.js:1199:10)
W20200611-11:38:41.267(7)? (STDERR)     at AccountsServer.userId (packages/accounts-base/accounts_server.js:91:60)
W20200611-11:38:41.267(7)? (STDERR)     at AccountsServer.user (packages/accounts-base/accounts_common.js:85:25)
W20200611-11:38:41.267(7)? (STDERR)     at Object.Meteor.user (packages/accounts-base/accounts_common.js:305:30)
W20200611-11:38:41.267(7)? (STDERR)     at currentComId (imports/api/lib/currentCompany.js:16:3)
W20200611-11:38:41.267(7)? (STDERR)     at model.default (imports/api/employees/employees.js:55:14)
W20200611-11:38:41.267(7)? (STDERR)     at SchemaString.SchemaType.getDefault (/Users/rabbit/Desktop/app/meteor-element/node_modules/mongoose/lib/schematype.js:887:25)
W20200611-11:38:41.267(7)? (STDERR)     at $__applyDefaults (/Users/rabbit/Desktop/app/meteor-element/node_modules/mongoose/lib/document.js:359:22)
W20200611-11:38:41.268(7)? (STDERR)     at model.Document (/Users/rabbit/Desktop/app/meteor-element/node_modules/mongoose/lib/document.js:138:5)
W20200611-11:38:41.268(7)? (STDERR)     at model.Model (/Users/rabbit/Desktop/app/meteor-element/node_modules/mongoose/lib/model.js:93:12)
W20200611-11:38:41.268(7)? (STDERR)     at new model (/Users/rabbit/Desktop/app/meteor-element/node_modules/mongoose/lib/model.js:4459:15)
W20200611-11:38:41.268(7)? (STDERR)     at Array.<anonymous> (/Users/rabbit/Desktop/app/meteor-element/node_modules/mongoose/lib/model.js:3241:15)
W20200611-11:38:41.268(7)? (STDERR)     at _start (/Users/rabbit/Desktop/app/meteor-element/node_modules/mongoose/lib/helpers/parallelLimit.js:23:37)
W20200611-11:38:41.268(7)? (STDERR)     at parallelLimit (/Users/rabbit/Desktop/app/meteor-element/node_modules/mongoose/lib/helpers/parallelLimit.js:19:5)
W20200611-11:38:41.268(7)? (STDERR)     at Function.Model.$__insertMany (/Users/rabbit/Desktop/app/meteor-element/node_modules/mongoose/lib/model.js:3262:3)
W20200611-11:38:41.268(7)? (STDERR)     at process.nextTick (/Users/rabbit/Desktop/app/meteor-element/node_modules/kareem/index.js:369:33)
W20200611-11:38:41.268(7)? (STDERR)     at _combinedTickCallback (internal/process/next_tick.js:132:7)
W20200611-11:38:41.268(7)? (STDERR)     at process._tickDomainCallback (internal/process/next_tick.js:219:9)

But if Schema not set default it’s done for insert.

Please, help me.

1 Like

If we look through the error stack for the first file in app code you find these two:

W20200611-11:38:41.267(7)? (STDERR)     at currentComId (imports/api/lib/currentCompany.js:16:3)
W20200611-11:38:41.267(7)? (STDERR)     at model.default (imports/api/employees/employees.js:55:14)

Which points to this default in your schema:

comId: {
    type: String,
    required: true,
    default: () => {
      // get current companyId
      return currentComId()
    },
    index: 1,
  },

It looks like the currentComId() relies on UserID, which needs the a fiber to read the method’s context (ie user session).
I don’t know why it’s lost the fiber, Mongoose must be calling that asynchronously.

To get the fiber back, we can try to use Meteor.bindEnvironment.

I’m not sure exactly where the right place here is, since I’m not familiar with mongoose, but I would try wrapping the default function first

    default: Meteor.bindEnvironment(() => {
      return currentComId()
    }),

And if that doesn’t work, try wrapping currentComId:

    default: () => {
      return Meteor.bindEnvironment(currentComId)()
    }),

EDIT:
Looking at Mongoose’s source a bit, there’s a lot of callbacks and asynchronicity, especially around this comment:

Which means it might not be possible to use Meteor.userID in mongoose schemas.

You might need to add that check before calling insertMany

2 Likes
// It got error like above 
default: () => {
      return Meteor.bindEnvironment(currentComId)()
}),

-------------
// It got error like below 
default: Meteor.bindEnvironment(() => {
      return currentComId()
}),

It got error :

I20200611-15:05:11.936(7)? Exception in callback of async function: Error: Meteor.userId can only be invoked in method calls or publications.
I20200611-15:05:11.936(7)?     at AccountsServer.userId (packages/accounts-base/accounts_server.js:93:13)
I20200611-15:05:11.936(7)?     at AccountsServer.user (packages/accounts-base/accounts_common.js:85:25)
I20200611-15:05:11.936(7)?     at Object.Meteor.user (packages/accounts-base/accounts_common.js:305:30)
I20200611-15:05:11.936(7)?     at currentComId (imports/api/lib/currentCompany.js:16:3)
I20200611-15:05:11.937(7)?     at Mongoose.Schema.comId.default.Meteor.bindEnvironment (imports/api/employees/employees.js:60:16)
I20200611-15:05:11.937(7)?     at runWithEnvironment (packages/meteor.js:1286:24)

Sounds like my speculation in the edit was right. I don’t think it’s possible to use Meteor.userId in mongoose schema definitions since they are processed through multiple layers of asynchronicity, disconnecting them from the method call and it’s associated user session.

You will likely need to pre-process the documents, and add the comId before calling insertMany

Yes , thank you for your help me :pray: :pray: